- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Lex 和 Yacc 可以同时对 Lex 和 Yacc 进行 lex 和解析吗?
换句话说,是否可以编写一个自托管的 Lex/Yacc 组合,生成自己的解析器?
编辑:我并不是说组合需要完全解析输入的 C 部分。特别是,它不需要处理 typedef-name/identifier 冲突,或构建一个完整的符号表(尽管我相信两者都可以在词法分析器和解析器中用 C 代码处理) .这是因为 C 代码被逐字复制到输出。
编辑 2:基本上,Lex 和 Yacc(语言,而不是程序)有 LALR(1) 语法吗?
最佳答案
好吧,答案实际上比第一个答案报告的要复杂。我声称,不,YACC 无法解析 YACC,但细节决定成败。
YACC 的自然语法包括:
gram: %empty | gram rule
rule: ID ":" rhs
rhs: %empty | rhs ID
(使用类似 Bison 的约定:":"
是无值标记,ID
是标识符标记,%empty
强调RHS 为空的规则)。
不难看出这个文法不是LR(1)。作为 LR(1) 大致意味着当您的光标前进时,您只需查看下一个标记就知道您在哪个规则中。然后考虑以下(有效)输入:
ID : ID ID
ID : ID
ID :
您能否轻易地辨别出一条规则何时开始以及下一条规则何时开始?好吧,这种方式太简单了,试着找出 YACC 会看到的:
ID : ID ID ID : ID ID :
您如何知道第一条规则何时完成?将光标的位置视为下面的 .
:
ID : ID . ID ID : ID ID :
第一条规则完成了吗?当然不是。下一步呢?
ID : ID ID . ID : ID ID :
第一条规则完成了吗?是的,很明显。但是在这两种情况下,下一个标记(也称为“先行”)都是 ID
;以下标记有助于确定当前规则是否完成(“:”
)或未完成(ID
)。换句话说,1 次前瞻是不够的,这个文法不是 LR(1),因此也不是 LALR(1)(这是 YACC 接受的文法类别)。显然是LR(2)。
如果我们接受更改语言并要求终止 ;
规则,那么使此语法成为 LR(1) 将非常容易:
ID : ID ID ; ID : ID ; ID : ;
不幸的是,为时已晚,POSIX 并未决定强制使用此分号,因此 YACC 的实现必须处理此 LR(2) 语法。
在 Bison 的情况下,它使用整洁/肮脏(取决于您的观点)技巧来处理它:扫描器被教导区分“常规”标识符(ID ) 和一个标识符后跟一个冒号 (ID_COLON)。然后 token 流读
ID_COLON ID ID ID_COLON ID ID_COLON
这显然是 LR(1)。
那么为什么从 YACC 开始就不需要分号呢?好吧,由于明显的引导原因,YACC 不能首先在 YACC 中编写,所以我猜 S. Johnson 从未意识到他手工编写的解析器实际上接受了比 LR(1) 更难的语法。 Bison 和 byacc 来自一个普通的克隆,其解析器也是手写的。 Bison 自己的解析器是在 2002 年启动的(commit e9955c83734d0a545d7822a1feb9c4a8038a62cb)。
我写的很多内容都可以根据您的看法进行辩论。我声称“自然”语法不是 LR(1),但我认为不能在这里定义“自然”。所以是的,别人可能会说YACC的文法是LR(1)。但最后,我们没问题,因为如果一种语言是 LR(k),那么它就是 LR(1)(即 LR(k) 文法可以变成 LR(1) 怪兽文法,即证明使用类似的肮脏/整洁的技巧)。
Wrt Flex,嗯,是的,它是自举的,但这样说也有点不真实:它的整体语法非常简单,很容易用正则表达式描述。然而,正则表达式本身逃脱了纯粹的常规语言的领域:有括号!所以在 Lex/Flex 内部的某个地方,必须有一个真正的解析器,无论是生成的还是手写的,来解析正则表达式。
询问 Lex 是否自举类似于询问 C 预处理器是否自举:是的,我确定那里有 #include
:)
关于bison - Lex 和 Yacc 可以对自己进行 lex 和解析吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24835803/
我有一个使用 Yacc 编写的语法。语法的相关部分摘录在这里 postfix : primary | postfix '[' expr ']' | postfix '[' ex
如何在 bison/yacc 中使用继承的属性? 说,我有这样的语法 - 程序 -> stmts 我想做的是在 Bison 身上: 程序:stmts {$$.next = newLabel(); $1
有什么方法可以更改 Bison 错误消息的格式?例如,不要说 syntax error, unexpected T_ID, expected ';' or T_IMPORT说 unexpected i
我的语法有这两个标记声明: %token RP %token ELSE 而这两条规则: Statement : IF LP Exp RP Statement; Statement : IF LP
如果有一个表单的输入文件: BEGIN stuff.... END BEGIN stuff ... END 我的 .y 文件是这样的 %token BEGIN %token END %star
我希望为现有语言创建一个 JavaScript 解析器,该语言目前具有笨拙的“手工制作”C# 和 Java 解析器。我想使用 Jison,并且也一直在尝试学习 Bison 的基础知识。 我不确定如何回
目前我正在研究一个源到源编译器,我已经编写了一个野牛解析器,可以正确地为输入创建 AST。我现在需要对语法树进行多次转换,因此我需要向树中插入许多节点。 我可以手动创建所有要添加到语法树中的结构体/联
如果有一个表单的输入文件: BEGIN stuff.... END BEGIN stuff ... END 我的 .y 文件是这样的 %token BEGIN %token END %star
我正在寻找为现有语言创建 JavaScript 解析器的方法,该语言目前具有笨拙的“手工制作”C# 和 Java 解析器。想用Jison,也在努力学习Bison的基础。 一个我不确定如何回答的问题是
我正在使用 flex/bison 编写解析器(我可以用 Python 编写解析器,但我总是更喜欢经典。) 当我用这个编译代码时: gcc -lfl -ly chance.tab.c lex.yy.c
正在使用 flex/bison 开发编译器。我的构建输出中有此警告。 警告:在默认操作中键入冲突 ('s' '') 请问有什么帮助吗? 最佳答案 它似乎与源中的 %token 和 %type 声明有关
考虑这个 lex.l 文件: %{ #include "y.tab.h" %} digit [0-9] letter [a-zA-Z] %% "+"
我正在为 bison 中的一个简单的 Pascal 编译器编写语法,我想可视化我在 pascal.y 中指定的语法的解析树。是否可以基于我的 pascal.y 文件以图形方式显示语法树? 最佳答案 野
我正在尝试编写一个能够使用以下输入的语法: begin #this is a example x = 56; while x > 0 do begin point 15
我正在尝试使用 BNF 语法编写 Flex/Bison 文件。但是,当我尝试编译时出现错误,而且我不确定如何调试它们。 BNF语法: ::= | head() ::=:: | @ | tail() |
我正在用 Flex/Bison 编写一个小程序来标记/解析我创建的查询语言。 我想知道是否有任何方法可以在 Flex/Bison 中创建任何关键字。 我的意思是:flex 将输入分解成一个标记列表,但
我正在尝试使用 flex 和 bison 创建过滤器,因为我想从复杂的语言中获取某些语法元素。我的计划是使用 flex + bison 来识别语法,并转储出感兴趣元素的位置。 (然后使用脚本根据转储的
我正在尝试实现一个可以进行浮点运算的 Flex/bison 计算器。我的 Flex 代码如下所示 %{ #include "calc.tab.h" #include void yyerror(cha
我正在尝试使用 FLEX 和 BISON 进行一些练习。 这是我写的代码: calc_pol.y %{ #define YYSTYPE double #include "calc_pol.tab.h"
我有一个使用括号和方括号作为分隔符的语法。当由 bison 生成的解析器输入带有不平衡分隔符的输入时,传递给 yyerror 的 YYLTYPE* 中的错误位置是输入的结尾。所以,例如,在输入 x
我是一名优秀的程序员,十分优秀!