我正在尝试使用解析器规则来识别我的语言的类型说明符。这是我的规则:
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]
我不完全确定问题是什么,因为我看到规则中没有歧义,只有在数组的情况下才会发生递归。
我不仅对知道如何解决这个问题感兴趣,而且还知道正在发生什么,以及在这种情况下,左递归在哪里确实存在问题。
答案 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 |