我把这个问题简化为一个非常简单的语法。
Model:
(greetings+=Greeting* | greetings+=FrGreeting*);
Greeting:
'Hello' person=ID '!';
FrGreeting:
'Bonjour' person=('jacques' | 'philippe') '!';
在文件中,您可以用英语或法语来问候,但不能同时用两者。我们只知道2名法国人的名字。
问题是你不能用英语问候雅克。
Hello jacques!
结果为mismatched input 'jacques' expecting RULE_ID
。我很困惑为什么会这样。我该如何解决?
修改 做这样的事情:
Greeting:
'Hello' person= AllNames '!';
FrGreeting:
'Bonjour' person=(FrenchNames) '!';
AllNames: ID | FrenchNames ;
FrenchNames: 'jacques' | 'philippe';
修复了编译错误问题。但是,它会阻止自动完成工作,jacques
和philippe
仍然会像关键字一样突出显示(即使写为Hello jacques!
)。
编辑2: 这似乎解决了自动完成错误:
Greeting:
'Hello' person= AllNames '!';
FrGreeting:
'Bonjour' person=('jacques' | 'philippe') '!';
AllNames: 'jacques' | 'philippe' | ID;
我的问题: 为什么1分支中的字符串常量会改变ID终端沿不同代码路径被摄取的方式?它是用终端实现的(这似乎与文档相矛盾)?这是一个错误吗?
我编辑的解决方案是否是实现此目标的最佳方式?
答案 0 :(得分:1)
这个语法对我来说没有多大意义,但我猜(如果我理解正确的话)你可以用以下方法做你想做的事:
Model:
(greetings+=Greeting* | greetings+=FrGreeting*);
Greeting:
'Hello' person=PersonName '!';
FrGreeting:
'Bonjour' person=PersonName '!';
PersonName : ID | 'jacques' | 'philippe';
答案 1 :(得分:1)
你正是解决问题的正确方法。并且,你接近原因。 原因是语法中的常量字符串是TOKEN。该ID也是一个令牌。它们都是词法术语。但“常量字符串”TOKEN被视为“关键字”。它比其他TOKEN具有更高的优先级。因此,当您在编辑器中输入“jacques”时,解析器会看到令牌“jacques”而不是令牌ID。但是,“问候”规则需要一个令牌ID。