接着前面的 <程序中,调用Bison和Flex结合的小例子> 那一篇,再来整点新东西:
http://www.cnblogs.com/gaojian/archive/2013/05/17/3083662.html
我想,实际的工作中,绝对不会像逆波兰式计算器那样简单,直接就在语法分析器里完成计算。
常常需要构造一颗语法树,然后把它传出来!例如各种数据库系统处理SQL文就是这样子。
上程序:
1 [root@lex total]# cat lexer.l 2 %{ 3 4 #include "y.tab.h" 5 #include <stdio.h> 6 7 8 #undef YY_INPUT 9 #define YY_INPUT(b,r,s) readInputForLexer(b,&r,s) 10 11 #ifndef YYSTYPE 12 #define YYSTYPE int 13 #endif 14 extern YYSTYPE yylval; 15 16 %} 17 18 DIGIT [0-9] 19 %% 20 21 \+ { printf("got plus\n"); return FUNCTION_PLUS; } 22 \- { printf("got minus\n"); return FUNCTION_MINUS; } 23 {DIGIT}* { printf("got number\n"); yylval = atoi(yytext); return NUMBER; } 24 \n { printf("got end of line\n"); return EOL;} 25 %% 26 27 28 void yyerror(char* s) { 29 printf("error %s \n",s); 30 } 31 32 int yywrap() { 33 return -1; 34 } 35 [root@lex total]#
这里,通过 yylval,在词法分析器运行的时候,保持数据。
再看句法分析程序:
目前先不要求这么高,暂时看看如何在此处获得数据。
1 [root@lex total]# cat parser.y 2 %{ 3 #include <stdio.h> 4 extern void yyerror(char* s); 5 extern int yylex(); 6 extern int readInputForLexer(char* buffer,int *numBytesRead,int maxBytesToRead); 7 %} 8 9 %token FUNCTION_PLUS FUNCTION_MINUS NUMBER EOL 10 11 %% 12 exp: 13 NUMBER FUNCTION_PLUS NUMBER { fprintf(stderr,"---\n"); } 14 | 15 NUMBER FUNCTION_MINUS NUMBER { 16 fprintf(stderr,"left value is: %d\n",$1); 17 fprintf(stderr,"right value is: %d\n",$3); 18 } 19 ; 20 %% 21 [root@lex total]#
此处,使用了 $1,$3等。
再看主程序:
1 [root@lex total]# cat myparser.c 2 #include <stdio.h> 3 #include <string.h> 4 5 int yyparse(); 6 int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead ); 7 8 static int globalReadOffset; 9 // Text to read: 10 static const char *globalInputText = "23 - 5"; 11 12 int main() { 13 globalReadOffset = 0; 14 yyparse(); 15 return 0; 16 } 17 18 int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead ) { 19 int numBytesToRead = maxBytesToRead; 20 int bytesRemaining = strlen(globalInputText)-globalReadOffset; 21 int i; 22 if ( numBytesToRead > bytesRemaining ) { numBytesToRead = bytesRemaining; } 23 for ( i = 0; i < numBytesToRead; i++ ) { 24 buffer[i] = globalInputText[globalReadOffset+i]; 25 } 26 *numBytesRead = numBytesToRead; 27 globalReadOffset += numBytesToRead; 28 return 0; 29 } 30 [root@lex total]#
运行结果:
[root@lex total]# yacc -d parser.y [root@lex total]# lex lexer.l [root@lex total]# gcc -o myparser *.c [root@lex total]# ./myparser got number got minus got number left value is: 23 right value is: 5 [root@lex total]#
下一篇,写一下如何构造一个结构保留语法分析的结果。
本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/archive/2013/05/17/3083959.html,如需转载请自行联系原作者