Parsing 使用%glr解析器和%merge规则进行错误的bison缩减
目前,我正在尝试为VHDL构建一个解析器 有一些C++解析器必须面对的问题。 VHDL的上下文无关语法生成解析 林而不是单个解析树,因为它 关于函数调用和数组订阅的模糊性Parsing 使用%glr解析器和%merge规则进行错误的bison缩减,parsing,bison,text-parsing,glr,Parsing,Bison,Text Parsing,Glr,目前,我正在尝试为VHDL构建一个解析器 有一些C++解析器必须面对的问题。 VHDL的上下文无关语法生成解析 林而不是单个解析树,因为它 关于函数调用和数组订阅的模糊性 foo := fun(3) + arr(5); 只有当解析器 会随身携带一个Hirachily类型识别符号表 它会用它来解决一些模棱两可的问题 我不想这样做,因为对于像 前面提到过,解析林不会以指数形式增长,但是 根据函数调用量和 数组订阅 (当然,除非有人会用以下语句折磨解析器) 由于bison强制用户只创建一个解析树,
foo := fun(3) + arr(5);
只有当解析器
会随身携带一个Hirachily类型识别符号表
它会用它来解决一些模棱两可的问题
我不想这样做,因为对于像
前面提到过,解析林不会以指数形式增长,但是
根据函数调用量和
数组订阅
(当然,除非有人会用以下语句折磨解析器)
由于bison强制用户只创建一个解析树,
我使用%合并属性递归地收集所有子树并
在singleton中的所谓AMBIG节点下添加了这些子树
阿斯特
结果看起来像
为了产生上述结果,我解析了令牌流“I=I(N);”。
我在parse.y文件中使用的语法的实质是
下面收集。它试图模仿VHDL中模棱两可的部分:
start: prog
;
/* I cut out every semantic action to make this
text more readable */
prog: assignment ';'
| prog assignment ';'
;
assignment: 'I' '=' expression
;
expression: function_call %merge <stmtmerge2>
| array_indexing %merge <stmtmerge2>
| 'N'
;
function_call: 'I' '(' expression ')'
| 'I'
;
array_indexing: function_call '(' expression ')' %merge <stmtmerge>
| 'I' '(' expression ')' %merge <stmtmerge>
;
你知道为什么野牛会重复使用上述方法吗
节点
我还写了一篇关于官方gnu邮件的错误报告
列出野牛,但没有回答这一点。
不幸的是,由于新stackoverflow的限制
用户,我无法提供此错误报告的任何链接…这是预期的行为
表达式
可以明确减少,减少的值由两种可能的模糊减少(包括该值)使用。记住,GLR和LR一样,是一个从左到右的解析器。执行缩减操作时,所有子缩减都已发生。其效果与在右侧使用终端没有区别;终端不会被人为复制,以便在使用它的不明确产品中产生不同的实例
对大多数人来说,这将是一个特性而不是一个bug,我并不是开玩笑。没有图结构堆栈,GLR具有指数级运行时。如果您真的想在合并解析树时对共享AST节点进行深度复制,那么您必须自己进行,但我建议您找到一种方法来利用解析林实际上是一个有向无环图而不是一棵树这一事实;您可能能够利用缺少重复的优势
start: prog
;
/* I cut out every semantic action to make this
text more readable */
prog: assignment ';'
| prog assignment ';'
;
assignment: 'I' '=' expression
;
expression: function_call %merge <stmtmerge2>
| array_indexing %merge <stmtmerge2>
| 'N'
;
function_call: 'I' '(' expression ')'
| 'I'
;
array_indexing: function_call '(' expression ')' %merge <stmtmerge>
| 'I' '(' expression ')' %merge <stmtmerge>
;
FCALL1 -> EXPR2 -> N2
ARRIDX1 -> EXPR1 -> N1