我正在设计自己的玩具语言,该语言可以编译成 Brainf*ck 代码,但遇到了索引运算符的运算符优先级问题。解析器由 Bisonc++ 生成,它的语法文件使用与其表兄弟 bison 和 bison++ 大致相同的语法。
由于 BF 中寻址内存的怪癖,我必须以不同的方式处理对数组元素的操作,这就是为什么我为它们生成特定规则的原因(我故意省略了规则的主体)。相关语法(不起作用)如下:
%right '='
// a bunch of other operators
%left '+' '-'
// more operators
%left indexing
expression:
variable
|
array_element
|
expression '+' expression
|
// a bunch more rules
;
array_subscript:
'[' expression ']'
;
array_element:
expression array_subscript %prec indexing
;
现在,我的印象是,通过indexing
为规则分配优先级array_element
,解析器将直接匹配其左侧的最小表达式。但是,请考虑以下代码:
10 + arr[0]
// is parsed as
(10 + arr)[0]
我无法弄清楚为什么会这样。当代码更改为10 + (arr[0])
时,解析器会执行预期的操作,我认为这证明这与运算符优先级有关。我尝试过的许多事情之一是使用未使用的符号作为索引运算符。例如:
// bottom-most operator in the precedence definition (replacing 'indexing'):
%left '@'
array_element:
expression '@' array_subscript
;
// Code:
10 + arr@[0] // is now parsed properly
由于某种原因,这解决了该问题。我在做一些根本错误的事情吗?我是否误解了 bison 等人中运算符优先级的工作方式?
提前致谢!
编辑
我已将我的 dev 分支推送到 github,其中包含一个包含最小工作示例的文件夹,包括 Makefile 和测试文件。要使用不同的语法规范(文件:)重建解析器grammar
,您可以运行make regenerate
,但这需要bisonc++
和flexc++
(可从 Debian 存储库获得)。要仅使用当前(有故障的)解析器构建项目,请运行make
.
https://github.com/jorenheit/brainfix/tree/better_indexing/arraybug