代码之家  ›  专栏  ›  技术社区  ›  Richard Sharpe

ANTLR4告诉我:不匹配的输入“little”应为{big',little}

  •  0
  • Richard Sharpe  · 技术社区  · 8 年前

    我有以下简单语法:

    grammar TestG;
    
    p : pDecl+ ;
    
    pDecl : endianDecl
        | dTDecl
        ;
    
    endianType : E_BIG
        | E_LITTLE
        ;
    
    endianDecl : 'endian' '=' endianType ';' ;
    
    dTDecl : 'dT' '[' STRING ']' '=' ID ';' ;
    
    STRING: '"'.*?'"' ;                //Embedded quotes?
    COMMENT: '#' .*? [\n\r] -> skip ;  // Discard comments for now
    ID :   [a-zA-Z][a-zA-Z0-9_]* ;
    WS :   [ \t\n\r]+ -> skip ;
    INT : ('0x')?[0-9]+ ;  // How to handle 0xDD and ensure non zero?
    E_BIG : 'big' ;
    E_LITTLE : 'little' ;
    

    当我跑步时 grun TestG p 并输入以下内容:

    endian = little;
    

    我得到以下信息:

    line 1:9 mismatched input 'little' expecting {'big', 'little'}
    

    我做错了什么?

    1 回复  |  直到 8 年前
        1
  •  1
  •   TomServo    8 年前

    因为你的lexer规则 ID 在这之前 E_LITTLE ,您的“小”输入被解读为 身份证件 .

    [@0,0:5='endian',<'endian'>,1:0]
    [@1,7:7='=',<'='>,1:7]
    [@2,9:14='little',<ID>,1:9] <== see here it's being lexed as an ID
    [@3,15:15=';',<';'>,1:15]
    [@4,18:17='<EOF>',<EOF>,2:0]
    line 1:9 mismatched input 'little' expecting {'big', 'little'}
    

    移动这些lexer令牌 在上面 我希望如此:

    STRING: '"'.*?'"' ;                //Embedded quotes?
    COMMENT: '#' .*? [\n\r] -> skip ;  // Discard comments for now
    E_BIG : 'big' ;
    E_LITTLE : 'little' ;
    ID :   [a-zA-Z][a-zA-Z0-9_]* ;
    WS :   [ \t\n\r]+ -> skip ;
    INT : ('0x')?[0-9]+ ;  // How to handle 0xDD and ensure non zero?
    

    从测试输入中产生正确的输出。

    [@0,0:5='endian',<'endian'>,1:0]
    [@1,7:7='=',<'='>,1:7]
    [@2,9:14='little',<'little'>,1:9] <== see here being lexed correctly
    [@3,15:15=';',<';'>,1:15]
    [@4,18:17='<EOF>',<EOF>,2:0]
    

    enter image description here

    请记住,对于lexer令牌,最长的匹配获胜,但在平局的情况下,最先出现的匹配获胜。这就是为什么您希望更具体的lexer令牌位于lexer令牌列表的顶部,而更一般的令牌(如标识符、字符串等)位于更远的地方。