前端编译原理 简述-jison
最近几年的项目技术难点都和编译原理,抽象语法树,代码编辑器 有关系。现在时间有点空,先从基础了解起来,让有些交互和提示能够更智能些。
编译原理-Parser
编译原理 其实就是 让计算机懂的 “437+734” 这样的字符串编程 sum 437, 734 计算机懂得的机器码。实际场景中可能是从一种高级语言编译成一种低级语言。
编译过程份成2个步骤:
1.词法分析
词法分析就是 通过定义的正则表达式,把输入的字符串变成一个个标记(token)。
“437+734” => NUM PLUS NUM
2.语法分析
根据定于的语法,把上边的token通过移进/归约自动机,一步步的移入,规约,变成抽象语法树,最终产生结构。
文法 E => NUM PLUS NUM => sum(437, 734);

这个编译代码的程序我们叫做解析器,分析器,Parser。
解析器生成器 parser generator
在实际情况中,有专门用来生成Parser的程序,解析器生成器。
前端的js语法分析器生成器,还是瞒多的 https://tomassetti.me/parsing-in-javascript/,不同的语法生成器支持的文法也有差别。
JISON介绍
项目中用到的是jison库,这个库支持(lr0, slr, lr1, ll, lalr)文法。一般我们程序中使用的是lalr文法。
可以通过debugger的方式去理解移入规约的过,和jison的使用。http://nolanlawson.github.io/jison-debugger/。
1.jison 文法格式 grammar
使用起来很简单,官网的文档也比较详细, http://zaa.ch/jison/docs/。定义jison文件,通过 node 命令 "jison 文件"生成Parser的js文件;
jison是bison在js端的实现,但是也不是完全实现了相关的功能。
从http://nolanlawson.github.io/jison-debugger/上就能看到下面的一些文法格式
/* 词法文法 */
%lex /* 选项设置 flex 最长匹配原则 case-insensitive 忽略大小写 */
%options flex case-insensitive %% \s+ /* skip whitespace */
[0-9]+("."[0-9]+)?\b return 'NUMBER'
<<EOF>> return 'EOF' /lex /*操作符优先级设置*/ %left '+' '-'
%left '*' '/' /*语法开始的非终结符号*/ %start expressions %%
/* 词法 */
expressions
: e EOF
{return $1;}
;
试了下http://dinosaur.compilertools.net/bison/bison_10.html#SEC84,bison文档上面的这个文法不支持,所以使用的时候自己要看着处理

2.jison的输出
jison生成的Parser的输出其实是文法自己定义的,可以是一个结果值,可以是ast树,也可以是用户自己在文法上面定义的结果
3.Parser.js
其实这个可以直接研究下源代码,源代码看起来虽然有些难度,主要是语法分析的逻辑,移入规则逻辑,标示符,终结符,非终结符号等等相关的定义,其他词法的逻辑。
和实际使用中的有的一些变量还是比较容易看懂,或者说debug一下大概就知道有哪些参数了。

文法定义中的参数
yy: 这个属性是用户自己定义的,在编译期间共享,这样也是代码更加灵活。
4.误区
在使用中,会有一些误区存在,特别是移入规约的顺序,可能和我们平时看代码存在差异。比如说上面的例子。

我们需要在RULE{expr}中的expr内容 有另外一种含义,
但是实际情况的执行顺序其实是先 expr规则规约,才是 RULE{expr}规则规约,所以在进行expr规约的时候并不知道它是在RULE{}里面的,所以我们通过Parser生成ast,再通过ast遍历来解决这个问题可能会更好一些。
前端编译原理 简述-jison的更多相关文章
- 前端编译原理 parser.js源码解读
前面已经介绍了一个jison的使用,在正常开发中其实已经够用下,下面主要是看了下parser.js代码解读下,作为一些了解. 下面以最简单的文法产生的parser做一些代码注释 下面是一些注释,标示了 ...
- 前端编译原理 笔记 -- BISON
前面总结的差不多了,这边记录下,零碎的相关阅读可以备忘的一些知识点 Bsion文档,下面是中文的地址 https://blog.csdn.net/chinamming/article/details ...
- 前端与编译原理 用js去运行js代码 js2run
# 前端与编译原理 用js去运行js代码 js2run 前端与编译原理似乎相隔甚远,各种热门的框架都学不过来,那能顾及到这么多底层呢,前端开发者们似乎对编译原理的影响仅仅是"抽象语法树&qu ...
- 前端与编译原理——用JS写一个JS解释器
说起编译原理,印象往往只停留在本科时那些枯燥的课程和晦涩的概念.作为前端开发者,编译原理似乎离我们很远,对它的理解很可能仅仅局限于"抽象语法树(AST)".但这仅仅是个开头而已.编 ...
- ButterKnife的原理简述
ButterKnife的原理简述 注解处理器Java5 中叫APT(Annotation Processing Tool),在Java6开始,规范化为 Pluggable Annotation Pro ...
- Atitit.编译原理与概论
Atitit.编译原理与概论 编译原理 词法分析 Ast构建,语法分析 语意分析 6 数据结构 1. ▪ 记号 2. ▪ 语法树 3. ▪ 符号表 4. ▪ 常数表 5. ▪ 中间代码 1. ▪ 临 ...
- Compiler Theory(编译原理)、词法/语法/AST/中间代码优化在Webshell检测上的应用
catalog . 引论 . 构建一个编译器的相关科学 . 程序设计语言基础 . 一个简单的语法制导翻译器 . 简单表达式的翻译器(源代码示例) . 词法分析 . 生成中间代码 . 词法分析器的实现 ...
- 学了编译原理能否用 Java 写一个编译器或解释器?
16 个回答 默认排序 RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和 ...
- 编译原理(一)绪论概念&文法与语言
绪论概念&文法与语言 以老师PPT为标准,借鉴部分教材内容,AlvinZH学习笔记. 绪论基本概念 1. 低级语言:字位码.机器语言.汇编语言.与特定的机器有关,功效高,但使用复杂.繁琐.费时 ...
随机推荐
- ORA-00911: invalid character 错误解决集锦
转: ORA-00911: invalid character 错误解决集锦 参考https://www.linuxidc.com/Linux/2017-05/144361.htm ORA-00911 ...
- osg::NodeVisitor osg3.4.0
x:-89.4588 y:-12.1245 z:-11.7807x:-89.4588 y:-6.44823 z:-11.7807x:-89.2164 y:-9.07239 z:-11.811x:-89 ...
- 算法习题---3.08循环小数(UVa202)
一:题目 输入整数a和b(<=a<=,<=b<=),输出a/b的循环小数表示以及循环节长度. 例如,a=,b=,小数表示为0.(),循环字节长度为21 当循环节长度超过50时, ...
- jmeter 查看结果树,获取响应体写法校验是否提取写法是否正确的方法
JSON Path Expression里面写入提出值的写法,点击Test测试提取
- robot用例执行常用命令(还没试)
执行命令 执行一个用例 robot -t “testcase_name“ data_test.robot 按用例文件执行 robot data_test.robot或者robot --suite “p ...
- Vidual Studio vs2013彻底卸载
我的win10 1803 2019年年中升级的,非常后悔,持续不间断的假死状态让人很无奈.又不舍得回退,因为很多保存的隐藏数据. 开始清理系统吧,东西越少性能越好,于是电脑就成了纯净版,甚至连 看到了 ...
- IIC挂死问题解决过程
0.环境:arm CPU 带有IIC控制器作为slave端,带有调试串口. 1.bug表现:IIC slave 在系统启动后概率挂死,导致master无法detect到slave. 猜测1:认为IIC ...
- 解决无/var/log/messages 问题
转载于:https://blog.csdn.net/C_Major/article/details/51321684 1 内核编程insmod后,Ubuntu查看日志无/var/log/message ...
- Counting Cliques(HDU-5952)【DFS】
题目链接:https://vjudge.net/problem/HDU-5952 题意:有一张无向图,求结点数量为S的团的数量. 思路:如果不加一点处理直接用DFS必然会超时,因为在搜索过程中会出现遍 ...
- python学习-44 程序的解耦 (不是特别懂的,回头在复习)
import os def file_handler(backend_data,res=None,type='fetch'): # 查询功能 if type == 'fetch': with open ...