程序中,調用Bison和Flex結合的小例子


網上的很多程序,對初次接觸Bison和Flex的人而言,都有點復雜,看最簡單的例子更好些:

http://stackoverflow.com/questions/1920604/how-to-make-yy-input-point-to-a-string-rather-than-stdin-in-lex-yacc-solaris

我稍微修改一下,說說自己的理解,也作為一個備忘:

Flex程序:

 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 %}
12 
13 DIGIT   [0-9]
14 %%
15 
16 \+      { printf("got plus\n"); return FUNCTION_PLUS; }
17 \-      { printf("got minus\n"); return FUNCTION_MINUS; }
18 {DIGIT}* { printf("got number\n"); return NUMBER; }
19 %%
20 
21 
22 void yyerror(char* s) {
23     printf("error %s \n",s);
24 }
25 
26 int yywrap() {
27     return -1;
28 }
29 [root@lex total]# 

這個程序說明了數字、加號、減號的識別規則

同時,為了讓yylex()可以讀入字符串而不是讀入文件,覆蓋了 YY_INPUT。

Bison(Yacc)程序:

 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
10 
11 %%
12 
13 expression:
14     NUMBER FUNCTION_PLUS NUMBER { printf("got plus expression!  Yay!\n"); }
15     |
16     NUMBER FUNCTION_MINUS NUMBER { printf("got minus expression! Yay!\n");}
17     ;
18 %%
19 [root@lex total]# 

這個程序說明了兩個表達式: 加法(NUMBER FUNCTION_PLUS NUMBER) 和 減法(NUMBER FUNCTION_MINUS NUMBER)。

主程序:

 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]# 

在主程序中,為了能夠讓 yylex讀取字符串,聲明了 readInputForlexer函數。

根據YACC的約定,yyparse()會去調用 yylex()。而yylex()調用 readInputForLexer,一次一次地返回給yyparse。

編譯和執行:

yacc -d parser.y
lex lexer.l
gcc -o myparser *.c
./myparser

執行結果:

[root@lex total]# ./myparser
got number
 got minus
 got number
got minus expression! Yay!
[root@lex total]#

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM