Antlr4语法意外错误(C ++目标)

时间:2018-02-08 07:07:40

标签: c++ parsing antlr4

我正在使用Antlr 4.7.1的C ++目标,某些输入字符串会触发意外错误。

不按语法文件解析的字符串是:

keys abc-def;

给出错误:

Line(1:5) Error(mismatched input 'abc-def' expecting {KEY_NAME_PATTERN, STRING_LITERAL})

奇怪的是,如果我在语法文件中交换KEY_NAME_IDENTIFIER和KEY_NAME_PATTERN规则的位置,那么上面的字符串就会解析ok,但是后面的字符串现在失败了(它没有交换规则位置就通过了):

get key abc-def;

所以我怀疑Antlr中有一个错误,但我不是100%肯定。

语法文件:

grammar ModelKeyValue;

start : keyvalue_statements ;

keyvalue_statements: ( del_statement | get_statement | set_statement | keys_statement ) ';'
    ;

del_statement:
    KEYWORD_DEL key_name
    ;

get_statement:
    KEYWORD_GET key_name
    ;

set_statement:
    KEYWORD_SET key_name literal_value
    ;

keys_statement:
    KEYWORD_KEYS key_name_pattern
    ;

keyword:
    KEYWORD_DEL
    | KEYWORD_GET
    | KEYWORD_SET
    | KEYWORD_KEYS
    ;

key_name:
    KEY_NAME_IDENTIFIER
    | STRING_LITERAL
    ;

key_name_pattern:
    KEY_NAME_PATTERN
    | STRING_LITERAL
    ;

literal_value:
    STRING_LITERAL
    ;

KEYWORD_DEL: D E L;
KEYWORD_GET: G E T;
KEYWORD_SET: S E T;
KEYWORD_KEYS: K E Y S;

KEY_NAME_IDENTIFIER: ([a-z]|[A-Z]|[0-9]|'!'|'@'|'#'|'$'|':'|'-')+;

KEY_NAME_PATTERN: ([a-z]|[A-Z]|[0-9]|'!'|'@'|'#'|'$'|':'|'-'|'_'|'%')+;

STRING_LITERAL:
    '\'' ( ~'\'' | '\'\'' )* '\''
    | '"' ('\\' ~('\r' | '\n') | ~('\\' | '"'| '\r' | '\n'))* '"'
    ;

fragment A: [aA];
fragment B: [bB];
fragment C: [cC];
fragment D: [dD];
fragment E: [eE];
fragment F: [fF];
fragment G: [gG];
fragment H: [hH];
fragment I: [iI];
fragment J: [jJ];
fragment K: [kK];
fragment L: [lL];
fragment M: [mM];
fragment N: [nN];
fragment O: [oO];
fragment P: [pP];
fragment Q: [qQ];
fragment R: [rR];
fragment S: [sS];
fragment T: [tT];
fragment U: [uU];
fragment V: [vV];
fragment W: [wW];
fragment X: [xX];
fragment Y: [yY];
fragment Z: [zZ];

WS: [ \t\r\n]+ -> skip ;

如果有人可以验证此问题或建议一个有用的修复,谢谢。

1 个答案:

答案 0 :(得分:1)

不,这不是一个错误。你误解了令牌化的工作原理。它是这样的:只要有2个(或更多)规则匹配相同数量的字符,例如输入KEY_NAME_IDENTIFIER的{​​{1}}和KEY_NAME_PATTERN,则首先定义规则"胜&#34 ;.词法分析者不会"听"到解析器(就像无扫描器解析器一样)。没有办法解决这个问题。

要解决此问题,只需在keys abc-def;制作中添加KEY_NAME_IDENTIFIER

即可
key_name_pattern