【问题标题】:Antlr4 how to discard all unmatched inputAntlr4如何丢弃所有不匹配的输入
【发布时间】:2016-02-18 05:01:20
【问题描述】:

我想在 C 源文件中添加所有预处理语句,并忽略所有其他语句。我尝试在词法分析器中添加最后一条规则,例如Unknown : . -> skip ; // or -> channel(HIDDEN) ;,或者在解析器中添加最后一条规则,例如:ignored : . ;,但它不起作用。

这是我的语法:

grammar PreProcessStatement;


pre_if_statement
: pre_if pre_elif* pre_else? pre_endif
;

pre_if      :   PreProcessBegin 'if'    statement;
pre_endif   :   PreProcessBegin 'endif' ;
pre_else    :   PreProcessBegin 'else'  ;
pre_elif    :   PreProcessBegin 'elif'statement ;
pre_define  :   PreProcessBegin 'define' statement;
pre_undef   :   PreProcessBegin 'undef'statement    ;
pre_pragma  :   PreProcessBegin 'pragma'statement;

statement
: IDENTIFIER
| statement Condition statement
| '(' statement (Condition | Logic_or | Logic_and) statement ')'
| statement (Logic_or | Logic_and) statement
;



Logic_or
: '||'
;

Logic_and
: '&&'
;
PreProcessBegin :   '#'     ;
Condition       : '==' | '>' | '>='|  '<' | '<='    ;
NUM             : INT | HEX     ;
STRID           : '"'ID'"'  ;
IDENTIFIER      : [a-zA-Z_0-9]+ ;
ID              :   [a-zA-Z_]+ ;
INT             :   [0-9]+ ;
HEX             : '0x'INT;
WS              :   [ \t\n\r]+ -> skip ;
NewLine         : ('\n' | '\r' | '\n\r');
MulLine     : '\\' NewLine -> skip ;
Unknown : .*? -> skip ; // or -> channel(HIDDEN) ;

输入:

#if (test == ttt)
#elif rrrr
#else
aaa
#endif

错误:

line 4:0 extraneous input 'aaa' expecting '#'

我已阅读下面的链接,但不起作用。 Skipping unmatched input in Antlr

我的语法有什么问题?

【问题讨论】:

    标签: antlr4


    【解决方案1】:

    说明

    aaa 输入与 Unknown 令牌不匹配。它将与在Unknown lexeme 之前定义的IDENTIFIER : [a-zA-Z_0-9]+ 标记匹配。

    解决方案

    修改令牌

    Unknown 词位定义放在其他标记之前。向这个词位添加一个语义谓词,它将检查行中的第一个字符是否不是# 字符。如果为真,则跳过整行直到NewLine 标记。

    Unknown : {getCharPositionInLine() == 0 && _input.LA(1) != '#'}? .*? NewLine -> skip;
    

    使用词法分析器模式

    当您发现 # 字符时,进入新的词法分析器模式 PREPROCESSOR。这允许我们从现在开始只使用在PREPROCESSOR 模式中定义的令牌。出现新行时退出此模式。因此,当我们退出该模式时,我们正在寻找两个标记:PreProcessBegin(以# 字符开头的行)和Unknown(没有# 的行)。否则,在PREPROCESSOR 模式下,我们将匹配任何其他常规语言中的语句。

    词法分析器示例:

    PreProcessBegin : '#' -> pushMode(PREPROCESSOR); // enter mode
    Unknown : .*? NewLine -> skip;                   // or skip the line
    
    mode PREPROCESSOR; // when in PREPROCESSOR mode use defined below tokens
    (...)
    Condition : '==' | '>' | '>='|  '<' | '<=';
    IDENTIFIER : [a-zA-Z_0-9]+ ;
    ID : [a-zA-Z_]+ ;
    INT : [0-9]+ ;
    (...)
    NewLine : ('\n' | '\r' | '\n\r') -> popMode; // exit mode
    

    【讨论】:

      猜你喜欢
      • 2022-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-11
      • 2022-12-09
      • 2013-02-14
      • 2019-10-03
      • 1970-01-01
      相关资源
      最近更新 更多