程序中,调用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]#

 

 

你可能感兴趣的:(Flex)