程序中,调用Bison和Flex结合的小例子(语法分析中处理数据)

来源:互联网 发布:金蝶数据库安装教程 编辑:程序博客网 时间:2024/04/30 00:00

接着前面的 <程序中,调用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 YYSTYPE12 #define YYSTYPE int13 #endif14 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 EOL10 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]# ./myparsergot numbergot minusgot numberleft value is: 23right value is: 5[root@lex total]#
复制代码

 下一篇,写一下如何构造一个结构保留语法分析的结果。