如何从这种语法中删除歧义(antlr4)

时间:2018-05-01 11:51:34

标签: syntax antlr

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

  1. anInstance:AClass.DoSomething()
  2. participant A -> participant B: Any character except for \r\n (<>{}?)etc.
  3. 让我们先调用一个strict语法和第二个free语法。在anInstance:AClass.DoSomething()中,我需要toID ':' 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)
     ;
    

1 个答案:

答案 0 :(得分:1)

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

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

根据您当前的词法规则,CONTENT会在遇到:时优先,因此永远不会匹配':' ID

对于ANTLR 4,在这种情况下你可能应该使用模式 - 当你在自由格式中遇到:时,切换到“免费”模式并定义词法分析器规则{ {1}}仅在“免费”模式下可用。

请参阅this question以了解ANTLR 4词法分析器模式的工作原理。