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

简介:

接着前面的 <程序中,调用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,如需转载请自行联系原作者

目录
相关文章
|
30天前
|
设计模式 安全 编译器
介绍GCC8 中少数几个能用的C++20 特性
介绍GCC8 中少数几个能用的C++20 特性
18 4
|
10月前
|
存储
编译与解释的区别
编译与解释的区别
97 0
|
C语言 机器学习/深度学习