类型说明符语法中的相互左递归

时间:2015-03-28 09:12:58

标签: antlr3

我正在尝试使用解析器规则来识别我的语言的类型说明符。这是我的规则:

type: TYPE | type '[' numexpr? ']' | MAP '(' TYPE ',' type ')';

TYPE : 'int'|'float'|'bool'|'string';

MAP: 'map'

有了这个,我试图解析像:

这样的表达式
int
float[]
float[][][][][5][4][3]
map(string, int[][])
map(map(string,int), map(int[][], int[]))

但是Antlr告诉我:

error(210):  The following sets of rules are mutually left-recursive [type]

我不完全确定问题是什么,因为我看到规则中没有歧义,只有在数组的情况下才会发生递归。

我不仅对知道如何解决这个问题感兴趣,而且还知道正在发生什么,以及在这种情况下,左递归在哪里确实存在问题。

1 个答案:

答案 0 :(得分:1)

如果您有一个非终端A,可以通过任意数量的步骤导出具有与其“最左侧令牌”相同的非终端的内容,则会发生左递归。

例如:A-> * Aa (点击此处了解更多信息:http://en.wikipedia.org/wiki/Left_recursion

在您的情况下,问题在于第一个派生规则的第二个子句:

type - >输入'['numepr? ']'

想象一下尝试编写一个解析它的程序。它会像:

ParseResult parseType(expr) {
     match(parseType(expr));
     //... other matches
}

正如您所看到的,您将获得无休止的递归。当然这只是LL解析器的问题。如果您使用LL解析器,则应重写规则以避免左递归。例如,就在我的头顶:

type:TYPE arraybrackets

arraybrackets:'['numexr? ']'arraybrackets |