【问题标题】:Antlr4: Skip line when it start with * unless the second char isAntlr4:以 * 开头时跳过行,除非第二个字符是
【发布时间】:2021-03-19 15:46:18
【问题描述】:

在我的输入中,以* 开头的行是注释行,除非它以*+*- 开头。我可以忽略 cmets,但需要获取其他的。

这是我的词法分析器规则:

WhiteSpaces : [ \t]+;
Newlines    : [\r\n]+;
Commnent    : '*' .*? Newlines -> skip ;
SkipTokens  : (WhiteSpaces | Newlines) -> skip;

一个例子:

* this is a comment line
** another comment line
*+ type value

所以,前两个是注释行,我可以跳过它。但我不知道要定义可以捕获最后一行的词法分析器/解析器规则。

【问题讨论】:

    标签: antlr4 language-design


    【解决方案1】:

    您的 SkipTokens 词法分析器规则永远不会匹配,因为规则 WhiteSpacesNewlines 放在它之前。有关词法分析器如何匹配标记的说明,请参阅此问答:ANTLR Lexer rule only seems to work as part of parser rule, and not part of another lexer rule

    要使其按预期工作,请执行以下操作:

    SkipTokens  : (WhiteSpaces | Newlines) -> skip;
    
    fragment WhiteSpaces : [ \t]+;
    fragment Newlines    : [\r\n]+;
    

    fragment 是什么,请查看此问答:What does "fragment" mean in ANTLR?

    现在,回答你的问题。您将Comment 规则定义为始终以换行符结束。这意味着在您的输入结束时不能有评论。因此,您应该让注释以换行符或 EOF 结尾。

    这样的事情应该可以解决问题:

    COMMENT
     : '*' ~[+\-\r\n] ~[\r\n]* // a '*' must be followed by something other than '+', '-' or a line break
     | '*' ( [\r\n]+ | EOF )   // a '*' is a valid comment if directly followed by a line break, or the EOF
     ;
    
    STAR_MINUS
     : '*-'
     ;
    
    STAR_PLUS
     : '*+'
     ;
    
    SPACES
     : [ \t\r\n]+ -> skip
     ;
    

    当然,这并不要求* 位于行首。如果你愿意,请查看此问答:Handle strings starting with whitespaces

    【讨论】:

      猜你喜欢
      • 2013-09-26
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      • 2016-01-02
      相关资源
      最近更新 更多