程序中,调用Bison和Flex结合的小例子(类似完成语法树)

简介:

接前面的例子:程序中,调用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]# 
复制代码
目录
相关文章
|
存储 索引 Perl
Perl项目中的面向对象、继承默认加载和正则表达式的使用方法
Perl项目中的面向对象、继承默认加载和正则表达式的使用方法
108 0
|
C语言 机器学习/深度学习