1

如何禁用所有 BNFC 内置规则,例如IdentInteger或用于分隔令牌的空格?

我发现它们无用烦人,因为它们会干扰我正在尝试编写的解析器。

我已经尝试重新定义它们,但词法分析器似乎继续为它们生成规则。我可以从生成的文件中手动删除它们,但我完全反对修改机器生成的代码。


关于他们为什么烦人的长版本。

我刚刚开始学习如何使用 BNFC。我尝试的第一件事是将我以前的工作从 Alex 转换为 BNFC。特别是我想只匹配“好”的罗马数字。我认为这很简单:罗马数字可以看作是一个序列

<thousand-part> <hundred-part> <tens-part> <unit-part>

他们不可能都是空的。所以一个数字要么有一个非空的thousand-part,并且可以是其余的任何东西,要么它有一个空的thousand-part,因此要么hundred-tens-要么unit- part必须是非空的。可以重复相同的事情直到单位的基本情况。

所以我想出了这个,这或多或少是我在 Alex 中所做的直接翻译:

N1.            Numeral ::= TokThousands HundredNumber     ;
N2.            Numeral ::= HundredNumberNE                ; --NE = Not Empty
N3.      HundredNumber ::=                                ;
N4.      HundredNumber ::= HundredNumberNE                ;
N5.    HundredNumberNE ::= TokHundreds TensNumber         ;
N6.    HundredNumberNE ::= TensNumberNE                   ;
N7.         TensNumber ::=                                ;
N8.         TensNumber ::= TensNumberNE                   ;
N9.       TensNumberNE ::= TokTens UnitNumber             ;
N10.      TensNumberNE ::= UnitNumberNE                   ;
N11.        UnitNumber ::=                                ;
N12.        UnitNumber ::= UnitNumberNE                   ;
N13.      UnitNumberNE ::= TokUnits                       ;


token TokThousands ({"MMM"} | {"MM"} | {"M"}) ;  -- No x{m,n} in BNFC regexes?
token TokHundreds  ({"CM"} | {"DCCC"} | {"DCC"} | {"DC"} | {"D"} | {"CD"} | {"CCC"} | {"CC"} | {"C"}) ;
token TokTens      ({"IC"} | {"XC"} | {"LXXX"} | {"LXX"} | {"LX"} | {"LX"} | {"L"} | {"IL"} | {"XL"} | {"XXX"} | {"XX"} | {"X"}) ;
token TokUnits     ({"IX"} | {"VIII"} | {"VII"} | {"VI"} | {"V"} | {"IV"} | {"III"} | {"II"} | {"I"}) ;

现在,问题是如果我尝试构建这个解析器,当给出如下输入时:

MMI

或者一般来说,如果一个数字有多个*-parts 不为空,则解析器会给出错误,因为 BNFC 无法MMI与单个令牌匹配,因此它使用内置Ident规则。由于该规则未出现在语法中,因此会引发解析错误,尽管输入字符串在我定义的语法中完全没问题,但这是一个伪造 Ident的规则。

注意:我验证了如果我用空格分隔不同的部分,我会得到正确的输入,但稍后我想用空格分隔整数,而不是它们的标记。

4

1 回答 1

0

根据 BNFC 的文档

这些类型是硬编码的,不能是规则的值类型

这意味着:如果不修改生成的代码,就无法禁用内置规则。唯一的选择是编写一个脚本,自动从生成的文件中删除虚假规则,并始终使用 aMakefile来构建词法分析器和解析器,以避免忘记该步骤。

似乎作者故意决定降低 BNFC 的灵活性,强加他们对整数文字是什么、标识符应该是什么样子、令牌应该如何分隔等的定义。他们本可以提供默认规则,允许使用一些禁用它们选项,但他们决定,如果您不同意他们的定义,那么您根本不应该使用他们的工具。

于 2014-02-19T22:25:14.657 回答