程序中,调用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]# 
复制代码
目录
相关文章
|
存储 编译器 C语言
详解C/C++中的static和extern
本文详解了C/C++中`static`和`extern`关键字的用法和区别,通过具体代码示例说明了在不同情境下如何正确使用这两个关键字,以及`extern "C"`在C++中用于兼容C语言库的特殊作用。
425 4
详解C/C++中的static和extern
|
机器人
如何查询OpenAI账户余额?ChatGPT怎么查看账户余额的方法
ChatGPT是美国OpenAI研发的聊天机器人程序,也是最近火爆全网的热门应用和话题之王。很多用户在使用openai的时候不知道如何查询OpenAI账户余额?
2755 0
|
自然语言处理 编译器
编译原理复习五:属性文法与三地址码的生成(附题目与答案 超详细)
编译原理复习五:属性文法与三地址码的生成(附题目与答案 超详细)
1002 0
|
数据库 索引
数据结构中平衡二叉树插入删除中左旋、右旋、左右双旋、右左双旋的详解(题目讲解 简单易懂)
数据结构中平衡二叉树插入删除中左旋、右旋、左右双旋、右左双旋的详解(题目讲解 简单易懂)
434 0
|
存储 缓存 安全
【C/C++ 关键字 存储类说明符 】 线程局部变量的魔法:C++ 中 thread_local的用法
【C/C++ 关键字 存储类说明符 】 线程局部变量的魔法:C++ 中 thread_local的用法
409 0
|
SQL 自然语言处理 Linux
探索 Linux 命令:Bison - 一个强大的语法分析器生成器
Bison是Linux下的一个语法分析器生成器,用于将上下文无关文法转换为C代码,简化编译器或解释器开发。它提供性能优化和灵活的语义动作定制,常用于创建解析器,如SQL解析器或自定义脚本语言解释器。通过编写.y文件定义语法规则,使用Bison生成解析器代码,然后集成到项目中,搭配词法分析器如Flex使用。Bison帮助开发者专注于应用逻辑,而非解析器实现。
|
算法 安全
金石原创 |【分布式技术专题】「分布式技术架构」一文带你厘清分布式事务协议及分布式一致性协议的算法原理和核心流程机制(Paxos篇)
金石原创 |【分布式技术专题】「分布式技术架构」一文带你厘清分布式事务协议及分布式一致性协议的算法原理和核心流程机制(Paxos篇)
598 1
金石原创 |【分布式技术专题】「分布式技术架构」一文带你厘清分布式事务协议及分布式一致性协议的算法原理和核心流程机制(Paxos篇)
|
开发工具 git
掌握Git必备:最常用的50个Git命令
掌握Git必备:最常用的50个Git命令
601 0
|
Web App开发 前端开发 JavaScript
谷歌浏览器chrome神级插件推荐
谷歌浏览器chrome神级插件推荐
|
缓存 监控 容灾
饿了么技术往事(下)
在商业竞争中,技术团队和其他团队一样,作为组织的一部分,应该是荣辱与共的。但是,就行业而言,饿了么创造的社会价值也是显而易见的,而且,饿了么塑造了这个行业最初的模样,对社会创造的价值影响是长远的!
9446 117
饿了么技术往事(下)