void yyerror( char *s ) { if( incp ) printf( "%s: line %d: ", incp->fname, incp->line ); printf( "%s at %s\n", s, symdump( &yylval ) ); ++anyerrors; }
void yyerror( const char * s ) { /* We use yylval instead of incp to access the error location information as * the incp pointer will already be reset to 0 in case the error occurred at * EOF. * * The two may differ only if we get an error while reading a lexical token * spanning muliple lines, e.g. a multi-line string literal or action body, * in which case yylval location information will hold the information about * where this token started while incp will hold the information about where * reading it broke. * * TODO: Test the theory about when yylval and incp location information are * the same and when they differ. */ printf( "%s:%d: %s at %s\n", object_str( yylval.file ), yylval.line, s, symdump( &yylval ) ); ++anyerrors; }
int yylex() { int c; char buf[ BIGGEST_TOKEN ]; char * b = buf; if ( !incp ) goto eof; /* Get first character (whitespace or of token). */ c = yychar(); if ( scanmode == SCAN_STRING ) { /* If scanning for a string (action's {}'s), look for the closing brace. * We handle matching braces, if they match. */ int nest = 1; while ( ( c != EOF ) && ( b < buf + sizeof( buf ) ) ) { if ( c == '{' ) ++nest; if ( ( c == '}' ) && !--nest ) break; *b++ = c; c = yychar(); /* Turn trailing "\r\n" sequences into plain "\n" for Cygwin. */ if ( ( c == '\n' ) && ( b[ -1 ] == '\r' ) ) --b; } /* We ate the ending brace -- regurgitate it. */ if ( c != EOF ) yyprev(); /* Check for obvious errors. */ if ( b == buf + sizeof( buf ) ) { yyerror( "action block too big" ); goto eof; } if ( nest ) { yyerror( "unmatched {} in action block" ); goto eof; } *b = 0; yylval.type = STRING; yylval.string = object_new( buf ); yylval.file = incp->fname; yylval.line = incp->line; } else { char * b = buf; struct keyword * k; int inquote = 0; int notkeyword; /* Eat white space. */ for ( ;; ) { /* Skip past white space. */ while ( ( c != EOF ) && isspace( c ) ) c = yychar(); /* Not a comment? */ if ( c != '#' ) break; /* Swallow up comment line. */ while ( ( ( c = yychar() ) != EOF ) && ( c != '\n' ) ) ; } /* c now points to the first character of a token. */ if ( c == EOF ) goto eof; yylval.file = incp->fname; yylval.line = incp->line; /* While scanning the word, disqualify it for (expensive) keyword lookup * when we can: $anything, "anything", \anything */ notkeyword = c == '$'; /* Look for white space to delimit word. "'s get stripped but preserve * white space. \ protects next character. */ while ( ( c != EOF ) && ( b < buf + sizeof( buf ) ) && ( inquote || !isspace( c ) ) ) { if ( c == '"' ) { /* begin or end " */ inquote = !inquote; notkeyword = 1; } else if ( c != '\\' ) { /* normal char */ *b++ = c; } else if ( ( c = yychar() ) != EOF ) { /* \c */ if (c == 'n') c = '\n'; else if (c == 'r') c = '\r'; else if (c == 't') c = '\t'; *b++ = c; notkeyword = 1; } else { /* \EOF */ break; } c = yychar(); } /* Check obvious errors. */ if ( b == buf + sizeof( buf ) ) { yyerror( "string too big" ); goto eof; } if ( inquote ) { yyerror( "unmatched \" in string" ); goto eof; } /* We looked ahead a character - back up. */ if ( c != EOF ) yyprev(); /* Scan token table. Do not scan if it is obviously not a keyword or if * it is an alphabetic when were looking for punctuation. */ *b = 0; yylval.type = ARG; if ( !notkeyword && !( isalpha( *buf ) && ( scanmode == SCAN_PUNCT ) ) ) for ( k = keywords; k->word; ++k ) if ( ( *buf == *k->word ) && !strcmp( k->word, buf ) ) { yylval.type = k->type; yylval.keyword = k->word; /* used by symdump */ break; } if ( yylval.type == ARG ) yylval.string = object_new( buf ); } if ( DEBUG_SCAN ) printf( "scan %s\n", symdump( &yylval ) ); return yylval.type; eof: /* We do not reset yylval.file & yylval.line here so unexpected EOF error * messages would include correct error location information. */ yylval.type = EOF; return yylval.type; }
int yylex() { int c; char buf[BIGGEST_TOKEN]; char *b = buf; if( !incp ) goto eof; /* Get first character (whitespace or of token) */ c = yychar(); if( scanmode == SCAN_STRING ) { /* If scanning for a string (action's {}'s), look for the */ /* closing brace. We handle matching braces, if they match! */ int nest = 1; while( c != EOF && b < buf + sizeof( buf ) ) { if( c == '{' ) nest++; if( c == '}' && !--nest ) break; *b++ = c; c = yychar(); /* turn trailing "\r\n" sequences into plain "\n" * for Cygwin */ if (c == '\n' && b[-1] == '\r') --b; } /* We ate the ending brace -- regurgitate it. */ if( c != EOF ) yyprev(); /* Check obvious errors. */ if( b == buf + sizeof( buf ) ) { yyerror( "action block too big" ); goto eof; } if( nest ) { yyerror( "unmatched {} in action block" ); goto eof; } *b = 0; yylval.type = STRING; yylval.string = newstr( buf ); yylval.file = incp->fname; yylval.line = incp->line; } else { char *b = buf; struct keyword *k; int inquote = 0; int notkeyword; /* Eat white space */ for( ;; ) { /* Skip past white space */ while( c != EOF && isspace( c ) ) c = yychar(); /* Not a comment? Swallow up comment line. */ if( c != '#' ) break; while( ( c = yychar() ) != EOF && c != '\n' ) ; } /* c now points to the first character of a token. */ if( c == EOF ) goto eof; yylval.file = incp->fname; yylval.line = incp->line; /* While scanning the word, disqualify it for (expensive) */ /* keyword lookup when we can: $anything, "anything", \anything */ notkeyword = c == '$'; /* look for white space to delimit word */ /* "'s get stripped but preserve white space */ /* \ protects next character */ while( c != EOF && b < buf + sizeof( buf ) && ( inquote || !isspace( c ) ) ) { if( c == '"' ) { /* begin or end " */ inquote = !inquote; notkeyword = 1; } else if( c != '\\' ) { /* normal char */ *b++ = c; } else if( ( c = yychar()) != EOF ) { /* \c */ *b++ = c; notkeyword = 1; } else { /* \EOF */ break; } c = yychar(); } /* Check obvious errors. */ if( b == buf + sizeof( buf ) ) { yyerror( "string too big" ); goto eof; } if( inquote ) { yyerror( "unmatched \" in string" ); goto eof; } /* We looked ahead a character - back up. */ if( c != EOF ) yyprev(); /* scan token table */ /* don't scan if it's obviously not a keyword or if its */ /* an alphabetic when were looking for punctuation */ *b = 0; yylval.type = ARG; if( !notkeyword && !( isalpha( *buf ) && scanmode == SCAN_PUNCT ) ) { for( k = keywords; k->word; k++ ) if( *buf == *k->word && !strcmp( k->word, buf ) ) { yylval.type = k->type; yylval.string = k->word; /* used by symdump */ break; } } if( yylval.type == ARG ) yylval.string = newstr( buf ); } if( DEBUG_SCAN ) printf( "scan %s\n", symdump( &yylval ) ); return yylval.type; eof: yylval.file = "end-of-input"; /* just in case */ yylval.line = 0; yylval.type = EOF; return yylval.type; }