如何从此语法中消除歧义 (antlr4)

How to remove ambiguity from this syntax (antlr4)

我正在写 a tool 从一些文本生成序列图。我需要支持这两种语法:

  1. anInstance:AClass.DoSomething()
  2. participant A -> participant B: Any character except for \r\n (<>{}?)etc..

我们称第一个为 strict 语法,第二个为 free 语法。在 anInstance:AClass.DoSomething() 中,我需要它与 to ( ID ':' ID ) 匹配,就像在 strict 语法中一样。但是,:AClass.DoSomething() 将首先与 CONTENT 匹配。我正在考虑某种前瞻性,检查 -> 是否存在但无法弄清楚。

Strict语法

message
 : to '.' signature
 ;
signature
 : methodName '()'
 ;
to
 : ID ':' ID
 ;
methodName
 : ID
 ;

ID
 : [a-zA-Z_] [a-zA-Z_0-9]*
 ;

Free语法

asyncMessage
 : source '->' target content
 ;
source
 : ID+
 ;
target
 : ID+
 ;
content
 : CONTENT
 ;

ID
 : [a-zA-Z_] [a-zA-Z_0-9]*
 ;
CONTENT
 : ':' ~[\r\n]+
 ;
SPACE
 : [ \t\r\n] -> channel(HIDDEN)
 ;

您需要了解 ANTLR 词法分析器的工作原理:

  • 它使用与输入的最长部分相匹配的规则(从当前位置开始)
  • 如果多个规则可以匹配相同的输入(即相同的长度),则使用第一个(按照它们定义的顺序)

根据您当前的词法分析器规则,只要您遇到 :CONTENT 就会优先,因此永远不会匹配 ':' ID

对于 ANTLR 4,在这种情况下您可能应该使用 模式 - 当您遇到自由形式的 : 时,切换到 "free"模式并定义词法分析器规则 CONTENT 仅在 "free" 模式下可用。

有关 ANTLR 4 词法分析器模式如何工作的想法,请参阅