ntoken = yylex(); while(ntoken) { printf("%d\n", ntoken); if(yylex() != COLON) { printf("Syntax error in line %d, Expected a ':' but found %s\n", yylineno, yytext); return1; } vtoken = yylex(); switch (ntoken) { case TYPE: case NAME: case TABLE_PREFIX: if(vtoken != IDENTIFIER) { printf("Syntax error in line %d, Expected an identifier but found %s\n", yylineno, yytext); return1; } printf("%s is set to %s\n", names[ntoken], yytext); break; case PORT: if(vtoken != INTEGER) { printf("Syntax error in line %d, Expected an integer but found %s\n", yylineno, yytext); return1; } printf("%s is set to %s\n", names[ntoken], yytext); break; default: printf("Syntax error in line %d\n",yylineno); } ntoken = yylex(); } return0; }
yylex() 只是返回一个 Token Type。但是这个 Token Type 在哪一行就是通过这个 yylineno 全局变量存储的。
yytext
yylex() 只是返回一个 Token Type。但是这个 Token Type 的字面量是什么是通过 yytext 这个全局变量存储的。
如果实在不理解,可以具体在程序中调试调试。
最后结果
1 2 3 4 5 6 7 8 9 10
$ gcc lex.yy.c myscanner.c -o myscanner $ ./myscanner < config.in 1 db_type is set to mysql 2 db_name is set to testdata 3 db_table_prefix is set to test_ 4 Syntax error in line 4, Expected an integer but found a1099
%{ voidyyerror(char *s); intyylex(); #include<stdio.h>/* C declarations used in actions */ #include<stdlib.h> #include<ctype.h> int symbols[52]; intsymbolVal(char symbol); voidupdateSymbolVal(char symbol, int val); %}
%union {int num; char id;} /* Yacc definitions */ %start line %token print %token exit_command %token <num> number %token <id> identifier %type <num> line exp term %type <id> assignment
%%
/* descriptions of expected inputs corresponding actions (in C) */
line : assignment ';' {;} | exit_command ';' {exit(EXIT_SUCCESS);} | print exp';' {printf("Printing %d\n", $2);} | line assignment ';' {;} | line print exp';' {printf("Printing %d\n", $3);} | line exit_command ';' {exit(EXIT_SUCCESS);} ;
assignment : identifier '='exp { updateSymbolVal($1,$3); } ; exp : term {$$ = $1;} | exp'+' term {$$ = $1 + $3;} | exp'-' term {$$ = $1 - $3;} ; term : number {$$ = $1;} | identifier {$$ = symbolVal($1);} ;
/* returns the value of a given symbol */ intsymbolVal(char symbol) { int bucket = computeSymbolIndex(symbol); return symbols[bucket]; }
/* updates the value of a given symbol */ voidupdateSymbolVal(char symbol, int val) { int bucket = computeSymbolIndex(symbol); symbols[bucket] = val; }
intmain(void) { /* init symbol table */ int i; for(i=0; i<52; i++) { symbols[i] = 0; }
%{ voidyyerror(char *s); intyylex(); #include<stdio.h>/* C declarations used in actions */ #include<stdlib.h> #include<ctype.h> int symbols[52]; intsymbolVal(char symbol); voidupdateSymbolVal(char symbol, int val); %}
/* returns the value of a given symbol */ intsymbolVal(char symbol) { int bucket = computeSymbolIndex(symbol); return symbols[bucket]; }
/* updates the value of a given symbol */ voidupdateSymbolVal(char symbol, int val) { int bucket = computeSymbolIndex(symbol); symbols[bucket] = val; }
intmain(void) { /* init symbol table */ int i; for(i=0; i<52; i++) { symbols[i] = 0; }