7 const char *Parser::currentLocation(
const char *io) {
8 const int LOCBUFFERSIZE = 1024;
9 static char loc_buf[LOCBUFFERSIZE+1];
12 if (last_line_start) {
13 int column = io - last_line_start + 1;
22 if (printed>LOCBUFFERSIZE) {
23 fprintf(stderr,
"AISC: Internal buffer overflow detected -- terminating [loc_buf]\n");
30 void Parser::p_err(
const char *io,
const char *
error) {
31 fprintf(stderr,
"%s: Error: %s\n", currentLocation(io), error);
36 # define HAVE_VSNPRINTF
39 # define PRINT2BUFFER(buffer, bufsize, templat, parg) vsnprintf(buffer, bufsize, templat, parg);
41 # define PRINT2BUFFER(buffer, bufsize, templat, parg) vsprintf(buffer, templat, parg);
44 #define ERRBUFFERSIZE 1024
45 void Parser::p_errf(
const char *io,
const char *formatString, ...) {
55 fprintf(stderr,
"AISC: Internal buffer overflow detected -- terminating [err]\n");
61 void Parser::copyTillQuotesTo(
const char*& in,
char*& out) {
63 bool quotes_closed =
false;
64 while (!quotes_closed) {
83 char *Parser::readWord(
const char *& in) {
91 copyTillQuotesTo(in, cp);
98 else copyWordTo(in, cp);
100 if (lastchar !=
EOSTR) skip_over_spaces_and_comments(in);
103 if (lastchar ==
EOSTR) {
104 p_err_exp_but_saw_EOF(in,
"terminator after string");
106 else if (cp != buf) {
108 result = strdup(buf);
114 char *Parser::SETSOURCE(
const char *& in,
enum TOKEN& foundTokenType) {
116 const char *
space = in+9;
118 if (*space !=
' ') p_err(in,
"space expected after '@SETSOURCE' (injected code)");
122 skip_over_spaces(in);
124 const char *file = in-1;
125 const char *comma = strchr(file,
',');
127 if (!comma) p_err(in,
"comma expected after '@SETSOURCE filename' (injected code)");
129 const char *end = strchr(comma,
'@');
131 if (!end) p_err(in,
"'@' expected after '@SETSOURCE filename,line' (injected code)");
140 result = parse_token(in, foundTokenType);
147 char *Parser::parse_token(
const char *& in,
enum TOKEN& foundTokenType) {
148 skip_over_spaces_and_comments_multiple_lines(in);
157 case ',': foundTokenType =
TOK_COMMA;
break;
158 case ';': foundTokenType =
TOK_SEMI;
break;
161 if (strncmp(in,
"SETSOURCE", 9) == 0) {
162 result = SETSOURCE(in, foundTokenType);
166 skip_over_spaces(in);
167 if (lastchar ==
EOSTR) {
168 p_err_exp_but_saw_EOF(in,
"ID behind '@'");
171 result = readWord(in);
178 result = readWord(in);
190 Header(
const char *key_) { key = strdup(key_); next =
NULp; }
203 char *loc_defined_at;
208 loc_defined_at =
NULp;
213 free(loc_defined_at);
214 loc_defined_at =
NULp;
220 head = tail = header;
221 loc_defined_at = strdup(location);
233 Token *Parser::parseBrace(
const char *& in,
const char *key) {
236 char *openLoc = strdup(currentLocation(in));
240 res =
new Token(key, block);
242 expect_and_skip_closing_brace(in, openLoc);
245 p_err_empty_braces(in);
259 bool reached_end_of_list =
false;
260 while (!error_flag && !reached_end_of_list) {
261 TOKEN foundTokenType;
262 char *
str = parse_token(in, foundTokenType);
265 switch (foundTokenType) {
268 reached_end_of_list =
true;
272 Token *sub = parseBrace(in, header ? header->
get_key() :
"{");
273 if (sub) items->
append(sub);
277 if (!header) p_err_exp_but_saw(in,
"string",
"','");
283 p_err_ill_atWord(in);
287 p_err_expected(in,
"ID behind '@'");
294 while (lastchar ==
',' && !error_flag) {
296 char *str2 = parse_token(in, foundTokenType);
297 if (foundTokenType !=
TOK_AT_WORD) p_err_exp_atWord(in);
301 if (!error_flag) expect_and_skip(in,
';');
304 reached_end_of_list =
true;
313 expect_line_terminator(in);
316 char *str2 = parse_token(in, foundTokenType);
317 switch (foundTokenType) {
319 new_token = parseBrace(in, str);
323 new_token =
new Token(str, str2);
324 expect_line_terminator(in);
329 new_token =
new Token(str,
"");
332 case TOK_AT_WORD: p_err_exp_string_but_saw(in,
"'@'");
break;
342 if (new_token) items->
append(new_token);
345 if (lastchar ==
';') {
349 sprintf(buf,
"value for @%s", missingVal->
get_key());
350 p_err_exp_but_saw(in, buf,
"';'");
352 else reached_end_of_list =
true;
361 p_err(in,
"Invalid token (internal error)");
366 if (!error_flag && header) header = header->
next_header();
371 if (error_flag || items->
empty()) {
384 while ((
EOSTR != lastchar) && (lastchar !=
'}')) {
385 TokenList *list = parseTokenList(in, headerList);
386 if (!error_flag && list) {
391 if (block->
empty() || error_flag) {
405 while (lastchar !=
EOSTR) {
406 skip_over_spaces_and_comments_multiple_lines(in);
408 if (lastchar ==
EOSTR)
break;
410 const char *p = in-1;
411 while ((lastchar !=
EOSTR) && (lastchar !=
'\n')) get_byte(in);
415 Code *& next = cl ? cl->
next : first_cl;
char * copy_string_part(const char *first, const char *last)
const char * get_path() const
static void error(const char *msg)
class Code * parse_program(const char *in, const char *filename)
#define PRINT2BUFFER(buffer, bufsize, templat, parg)
TokenListBlock * parseTokenListBlock(const char *&in)
void set_source(const Location &other)
#define aisc_assert(cond)
void append(TokenList *cmd)