0.概述:

  看了编译器龙书和虎书后,自己手动写了一个LALR(1)语法分析生成器,使用的语法文件格式和lemon的差不多。

  程序里面很多的算法也都是摘录自虎书,龙书虽然讲的很详细,但是真正动手写的时候还是虎书上面的算法给力点。程序相对来说比较简单,没有做任何优化,如果看过虎书和龙书,看懂代码难度不大。代码文件bytes.hpp和bytes.cpp中是主要的代码,TEMPLATE.hxx和TEMPLATE.cxx是语法分析生成器的模板文件。首先直接用make进行编译,然后进入到test目录中,运行生成器程序文件,参数是语法说明文件。执行成功后会生成会文件PARSER.hxx和PARSER.cxx,这两个文件就是你需要的语法分析器了。下面是个简单的实例说明下。

  1.语法说明文件:

这里用一个简单的计算器来说明语法说明文件的用法。下面是计算器的语法说明文件。

%include { #include <iostream> }
%token { int }
%syntax_error { std::cout << "Error: Syntax error.\n" << std::endl;}
#left PLUS MINUS
#left TIMES DIVprogram -> exp(A). { std::cout << "Result=" << A << std::endl; }exp(A) -> exp(B) MINUS exp(C). { A = B - C; std::cout << A << "=" << B << "-" << C << std::endl; }
exp(A) -> exp(B) PLUS exp(C). { A = B + C; std::cout << A << "=" << B << "+" << C << std::endl; }
exp(A) -> exp(B) TIMES exp(C). { A = B * C; std::cout << A << "=" << B << "*" << C << std::endl; }
exp(A) -> exp(B) DIV exp(C). {if(C != 0){A = B / C;}else{std::cout << "Divide by zero." << std::endl;}std::cout << A << "=" << B << "/" << C << std::endl;
}exp(A) -> INT(B). { A = B; std::cout << A << "=" << B << std::endl;}

终结符:终结符的名称只能由大写字母组成,在生成PARSER.hxx文件中会包括所有终结符的枚举定义。词法分析器的分析结果要和这里定义的枚举值一致。

  非终结符:非终结符由小写字母、下划线组成,非终结符只存在于生成语法分析器的过程中。生成的语法分析器不会包括非终结符。

  %include:这个说明符指定了生成的语法分析程序中要包含的头文件,这个指示符的格式是后面必须用大括号。如果有多个头文件可以用回车。

  %token:这个是token结构的指示符,必须在大括号中指定,目前只支持内建的数据类型。

  %syntax_error:语法分析过程中出现错误时,需要执行的代码。

  #left:左结合指示符。同时会指定优先级,越往后面的优先级越高。

  #right:右结合指示符。同left一样会指定优先级。

  program:是语法开始指示符,语法说明文件必须指定program生成式,否则会报错。

  BNF范式(产生式):每个产生式必须以非终结符开始,以 . 符号结束。产生式中的每个非终结符都可以起别名,方便在语义代码中使用,别名必须紧跟在非终结符后面,而且要括在小括号中。需要注意的是xbytes不支持,一行多个产生式,因此每行只能写一个产生式。

  语义代码:每个产生式的后面可以在大括号中指定产生式的语义代码。这个大括号要放到产生式最后的 . 点前面。语义代码只要是C++或者C代码就可以,没有其他限制。

  语法说明文件名:因为我写的语法分析生成器的名字叫xbytes,所以我把语法说明文件的后缀名指定为.x。比如上面计算器的语法说明文件名:calculate.x 。当然这个文件的后缀名是可以随便起的,即使没有也没有关系。

  ACTION.txt:在生成语法分析器的同时,会生成一个名为ACTION.txt的文件。文件中以很友好的方式将语法分析器的动作表打印出来了。可以帮助用户理解LALR(1)语法分析器的运作过程。

  备注:在xbytes.cpp代码文件中,包含许多dump_开头的函数。这些函数可以输出很多生成分析器过程中的数据。包括Symbol集合、规则集合、First集、Follow集、状态集和动作表等。

  2.语法分析器使用方式:

在根目录下直接输入 make 。编译xbytes,生成的可执行程序会被移入test目录中,进入test目录,然后执行./x calculate.x 就可以生成,简单计算器的语法分析程序了。使用这个程序的方式是自己写一个main.cpp文件,文件内容如下:

#include "PARSER.hxx"
#include <iostream>int main()
{xbytes::parser p;//5 * 3 + 6 / 2 - 8p.eat(INT, 5);p.eat(TIMES, 0);p.eat(INT, 3);p.eat(PLUS, 0);p.eat(INT, 6);p.eat(DIV, 0);p.eat(INT, 2);p.eat(MINUS, 0);p.eat(INT, 8);p.eat(0, 0);return 0;
}

使用方式很简单,首先要自己写个词法分析器,来进行词法分析,然后将词法分析得到的token一个个的喂给parser就可以了。parser::eat函数的第一个参数是token的类型,第二个参数是token的值。读取结束后,最后写入0,就是结束分析。

3.运行结果:

这里计算的是算式 5 * 3 + 6 / 2 - 8 的值。打印的是规约的过程,具体要打印的信息可以自己在语法说明文件的语义代码中自己定制。

[kiven@localhost test]$ ./XP
5=5
3=3
15=5*3
6=6
2=2
3=6/2
18=15+3
8=8
10=18-8
Result=10

4.代码:

目前的代码我只在CentOS下面测试过,其他平台没有经过测试。代码地址:https://github.com/kiven-li/xbytes

  5.展望:

  目前程序也仅仅只是能够生成语法分析器,但是性能不是很好,实用性也不是很高。后续要优化下程序性能,token要支持自定义结构。

转载于:https://www.cnblogs.com/kiven-code/p/4477587.html

LALR(1)语法分析生成器--xbytes相关推荐

  1. lemon语法分析生成器的使用以及源代码分析

    特点以及优点 1.Lemon是一个C或者C++语言的LALR(1)语法分析器生成器. 2.它和"bison"与"yacc"的功能是一样的,但它不是"b ...

  2. java语法分析生成器,语法词法生成器

    一.语法词法生成器 Flex 语法扫描器生成器 flex (fast lexical analyser generator) 是Lex的另一个替代品.它经常和自由软件Bison语法分析器生成器 一起使 ...

  3. JavaCC首页、文档和下载 - 语法分析生成器 - 开源中国社区

    JavaCC首页.文档和下载 - 语法分析生成器 - 开源中国社区

  4. 自己写语法分析生成器

    1.   控制参数 1.1.命令行参数 d 输出单独的定义文件 h 打印帮助信息 l 在生成的代码中生成#line t 在生成的代码中将YYDEBUG使能 v 将分析过程中的详细信息输出到output ...

  5. 语法分析生成器 - LEX

    [转载]The Lex & Yacc Page Lex - A Lexical Analyzer Generator M. E. Lesk and E. Schmidt ABSTRACT Le ...

  6. 基于语法分析的公式分析器设计

    摘要 本论文研究编译原理,使用LEX&YACC工具,编写数学公式分析器. 编译原理是计算机专业的一门重要专业课,通过编写数学公式分析器,加深对专业知识的理解. 本论文编写的数学公式分析器,可以 ...

  7. 【Bison学习笔记】1:生成简易的语法分析程序,使Bsion和Flex协同工作

    简述 Bison是在Yacc上改写并添加了大量特性后诞生的语法分析生成器,在编译前端(词法分析->语法分析->语义分析)中处在中间的位置,它可以用来生成特定的语法分析程序. 安装Bison ...

  8. java语言生成语法分析_语法分析器自动生成工具一览

    最近打算重做以前的一个留下遗憾的工作,当中的一项小任务就是要求编写一个简易SQL语言的语法分析器. 本科的<编译原理>课程依稀在我脑中留下些许映象.当初的课程大作业是写一个叫Dicuf(貌 ...

  9. Python之父发文,将重构现有核心解析器

    原题 | PEG Parsers 作者 | Guido van Rossum 译者 | 豌豆花下猫 转载自 Python猫(ID: python_cat) 导语:Guido van Rossum 是 ...

最新文章

  1. 和对象一起运动更快乐!看完这篇正经研究,找对象的理由又多了一个
  2. java主动抛出400异常_400个线程同时查询数据,抛出一个异常
  3. 带通采样定理简单记录
  4. python实现人像美颜
  5. VBS转化为exe可执行文件实例演示,vbs转exe工具推荐
  6. 柳编产业临沭谋定转型升级 农民丰收节交易会技能兴鲁
  7. 爬空气质量MySQL_爬虫:利用selenium采集某某环境网站的空气质量数据
  8. 二叉树的先序、中序、后序遍历等基本操作c++实现
  9. 年终总结 | 2019年人工智能+计算机视觉+深度学习笔记思维导图汇总
  10. C++ STL pair方法详解
  11. Python案例:输出指定要求的回文日期
  12. 对DNN的一些高层架构设想
  13. linux 测试网络端口通不通_【干货】网络中的各种互通与不通
  14. java求最大值时i的值_java 输入一组数组,求最大值。
  15. powerdesigner安装之后会自动加载到word中怎么去除??
  16. 灵魂拷问:你写的SQL一般有几个join ?​
  17. python大作业报告(爬虫 分析 可视化)_python第四次周末大作业
  18. 基本标示符-宏-编译连接
  19. Word数学公式编辑器怎么用
  20. SLAM学习——BA(Bundle Adjustment)与图优化

热门文章

  1. 动态规划简单应用:斐波那契数列
  2. matlab函数采样,[转载]matlab采样函数
  3. mysql 主从 问题_Mysql解决主从不同步问题
  4. java code combat_极客战记怎么换成java_「网易官方」极客战记(codecombat)攻略-沙漠-脆弱的士气......
  5. curl命令java_让 Bug 无处藏身,Java 线上问题排查思路、常用工具
  6. macappstore登不上去_武功山观星归来,缆车登顶,不徒步攻略!
  7. mac运行python速度慢_python-3.x – Pygame简单循环在Mac上运行得非常慢
  8. pythonturtle库使用心得_记录我的Python学习之旅(一)关于turtle库的基本用法
  9. Java connot reduce_Java8: Reduce方法
  10. python ioc di_Sping(一)——IOC/DI