接前面的例子:程序中,调用Bison和Flex结合的小例子
要做出存储语法树结构的全局变量:
1 [root@lex ~]# cd /soft/total 2 [root@lex total]# ls 3 lexer.l lex.yy.c myparser myparser.c myparser.h parser.y y.tab.c y.tab.h 4 [root@lex total]# cat myparser.h 5 typedef struct ABlock{ 6 int left; 7 int right; 8 }AB; 9 10 typedef struct MBlock{ 11 int left; 12 int right; 13 }MB; 14 15 typedef struct Parsetree{ 16 int flag; /*0 is init,1 is adding, 2 is minusing*/ 17 AB adding; 18 MB minusing; 19 }Parse, *Pointer; 20 Pointer pointer; 21 [root@lex total]#
主程序中,要完成以下几件事:
声明语法树指针(实际在上述头文件中完成)
调用词法分析/语法分析,得到语法树
根据语法树进行运算
1 [root@lex total]# cat myparser.c 2 #include <stdio.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include "myparser.h" 6 7 int yyparse(); 8 int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead ); 9 10 static int globalReadOffset; 11 // Text to read: 12 static const char *globalInputText = "23 - 5"; 13 14 int main() { 15 16 pointer=malloc(sizeof(struct Parsetree) ); 17 pointer->flag=0; 18 19 globalReadOffset = 0; 20 yyparse(); 21 22 //calculation 23 if (pointer->flag ==1){ 24 fprintf(stderr,"addding result is: %d\n",pointer->adding.left + pointer->adding.right); 25 } 26 27 if (pointer->flag ==2){ 28 fprintf(stderr,"minusing result is: %d\n",pointer->minusing.left - pointer->minusing.right); 29 } 30 31 free(pointer); 32 return 0; 33 } 34 35 int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead ) { 36 int numBytesToRead = maxBytesToRead; 37 int bytesRemaining = strlen(globalInputText)-globalReadOffset; 38 int i; 39 if ( numBytesToRead > bytesRemaining ) { numBytesToRead = bytesRemaining; } 40 for ( i = 0; i < numBytesToRead; i++ ) { 41 buffer[i] = globalInputText[globalReadOffset+i]; 42 } 43 *numBytesRead = numBytesToRead; 44 globalReadOffset += numBytesToRead; 45 return 0; 46 } 47 [root@lex total]#
词法分析和句法分析基本不变:
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]#
1 [root@lex total]# cat parser.y 2 %{ 3 #include <stdio.h> 4 #include "myparser.h" 5 extern void yyerror(char* s); 6 extern int yylex(); 7 extern int readInputForLexer(char* buffer,int *numBytesRead,int maxBytesToRead); 8 %} 9 10 11 %token FUNCTION_PLUS FUNCTION_MINUS NUMBER EOL 12 13 %% 14 exp: 15 NUMBER FUNCTION_PLUS NUMBER { 16 fprintf(stderr,"---\n"); 17 pointer->flag=1; 18 pointer->adding.left=$1; 19 pointer->adding.right=$3; 20 } 21 | 22 NUMBER FUNCTION_MINUS NUMBER { 23 fprintf(stderr,"left value is: %d\n",$1); 24 fprintf(stderr,"right value is: %d\n",$3); 25 pointer->flag=2; 26 pointer->minusing.left=$1; 27 pointer->minusing.right=$3; 28 } 29 ; 30 %% 31 [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 minusing result is: 18 [root@lex total]#