java-如何为ANTLR中的歧义输入生成多个分析树

我面临一个模棱两可的情况,其中可以使用不同的规则来解析输入字符串,我需要考虑这两个选项并为其生成多个解析树.

为了简单起见,考虑一个人的名字,例如“ Alber Johanson”,这个名字可以被解析为

(fullName (firstName Alber) (lastName Johanson)) 

或解析为

(fullName (firstName Alber) (lastName Johan) (relation son)) 

首先,如何配置规则以处理第二种情况?因为它是第二个字符串的一部分,而不是单独的标记.

其次,如何为输入字符串的所有可能选项生成分析树?

更新

这是我的语法示例,只能用于解析第一种情况,不能解析第二种情况

fullName: firstName lastName | firstName lastName relation;
firstName: NAME;
lastName: NAME;
relation: REL;

NAME: ('a'..'z'|'A'..'Z')+;
REL: 'son';

WHITESPACE : ('\t' | ' ' | '\r' | '\n'| '\u0020' | '\u000C' )+ -> skip ;

解决方法:

ANTLR不允许您按照自己的方式进行操作.然而,原因不是模棱两可,而是令牌化程序.

由于ANTLR词法政策,“ Johanson”一词始终被词法化为NAME:

>返回匹配时间最长的令牌
>如果两个令牌匹配的长度相同,则首选第一个定义的令牌

令牌REL将永远不会发生,因为

>任何后缀为“ son”的单词均为NAME(最长匹配)
>任何以“ son”为前缀的单词都是NAME(最长匹配)
>但一个孤立的单词“儿子”是一个名字(REL匹配但未首先定义)

回答第一个问题:
它不能由ANTLR解析器处理,因为它依赖于解析之前的标记化.您有两种选择:

>使用解析器生成器,使您可以对定向的解析器进行标记化(PEG解析器如煮熟的,老鼠应该这样做)
>丢弃令牌REL,并在访问解析树时解析姓氏

回答第二个问题:

上面的两个选择都很难解决打印相同字符序列的可能解释的问题.

PEG解析器旨在通过设计偏爱第一个替代方案,因此,如果找到有效的解释,它将不会进一步进行探讨.

ANTLR尚未设计成驱动解析器指示的词法分析器.如果您决定重新解析姓氏,那么使用纯Java来查找解释可能比编写新的词法分析器/解析器来查找它们更容易.

上一篇:为python安装stringtemplate3


下一篇:在哪里获取Python ANTLR包以使用StringTemplate?