Antlr4 语法歧义 [英] Antlr4 grammar ambiguity

查看:38
本文介绍了Antlr4 语法歧义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下语法(为 SO 最小化)

语法 你好;odataIdentifier : identifierLeadingCharacter identifierCharacter*;identifierLeadingCharacter : Alpha|下划线;identifierCharacter : identifierLeadingCharacter |数字;identifierUnreserved : identifierCharacter |(减号 | 点 | 波浪号);数字 : ZERO_TO_FIVE |[6-9];ONEHUNDRED_TO_ONEHUNDREDNINETYNINE : '1' 数字;//100-199TWOHUNDRED_TO_TWOHUNDREDFOURTYNINE : '2' ZERO_TO_FOUR 数字;//200-249TWOHUNDREDFIFTY_TO_TWOHUNDREDFIFTYFIVE : '25' ZERO_TO_FIVE;//250-255TEN_TO_NINETYNINE : ONE_TO_NINE 数字;//10-99零到一:[0-1];ZERO_TO_TWO : ZERO_TO_ONE |[2];ZERO_TO_THREE : ZERO_TO_TWO |[3];ZERO_TO_FOUR : ZERO_TO_THREE |[4];ZERO_TO_FIVE : ZERO_TO_FOUR |[5];ONE_TO_TWO : [1-2];ONE_TO_THREE : ONE_TO_TWO |[3];ONE_TO_FOUR : ONE_TO_THREE |[4];ONE_TO_NINE : ONE_TO_FOUR |[5-9];阿尔法:[a-zA-Z];减 : [-];点:'.';下划线:'_';波浪号:'~';WS : (' '|'\r'|'\t'|'\u000C'|'\n') ->跳过;

对于输入 c9 它工作正常,但是当我有 2 个数字例如 c10 它说:

额外的输入'92'期待{, Digit, Alpha, '_'}

所以我猜它解析 9 并解析 2 并且不知道这应该是 TEN_TO_NINETYNINE 还是 2 Digit Digit.我是个菜鸟,所以想知道我的分析是否正确,我该如何缓解这种情况......

解决方案

您的输入产生一个 Alpha 标记,后跟一个 TEN_TO_NINETYNINE 标记.虽然解析器规则 identifierLeadingCharacter 确实允许 Alpha 标记,但 identifierCharacter 规则不能匹配 TEN_TO_NINETYNINE 标记.>

输入 10 总是会产生一个 TEN_TO_NINETYNINE 标记而不是两个 Digit 标记,因为前者匹配更多的输入和词法分析器规则很贪心.

I have the following grammar ( minimized for SO)

grammar Hello;

odataIdentifier  : identifierLeadingCharacter identifierCharacter*; 


identifierLeadingCharacter : Alpha| UNDERSCORE;
identifierCharacter :  identifierLeadingCharacter | Digit;
identifierUnreserved    : identifierCharacter | (MINUS | DOT | TILDE);

Digit  : ZERO_TO_FIVE |[6-9];

ONEHUNDRED_TO_ONEHUNDREDNINETYNINE : '1' Digit Digit;            // 100-199
TWOHUNDRED_TO_TWOHUNDREDFOURTYNINE : '2' ZERO_TO_FOUR Digit;     // 200-249
TWOHUNDREDFIFTY_TO_TWOHUNDREDFIFTYFIVE : '25' ZERO_TO_FIVE;      // 250-255
TEN_TO_NINETYNINE : ONE_TO_NINE Digit;                           // 10-99

ZERO_TO_ONE : [0-1];
ZERO_TO_TWO : ZERO_TO_ONE | [2];
ZERO_TO_THREE : ZERO_TO_TWO | [3];
ZERO_TO_FOUR : ZERO_TO_THREE | [4];
ZERO_TO_FIVE : ZERO_TO_FOUR | [5];

ONE_TO_TWO  : [1-2];
ONE_TO_THREE  : ONE_TO_TWO | [3];
ONE_TO_FOUR  : ONE_TO_THREE | [4]; 
ONE_TO_NINE  : ONE_TO_FOUR | [5-9]; 

Alpha  : [a-zA-Z];

MINUS : [-];
DOT : '.';
UNDERSCORE : '_';
TILDE : '~';

WS  :  (' '|'\r'|'\t'|'\u000C'|'\n') -> skip
    ;

for input c9 it works fine, but when i have 2 digits for example c10 it says:

extraneous input '92' expecting {<EOF>, Digit, Alpha, '_'}

so i guess it parses 9 and parses 2 and doesn't know if this should be TEN_TO_NINETYNINE or 2 Digit Digit. i am a noob to this, so wondering if my analysis is right and how could i alleviate this ...

解决方案

Your input is resulting in an Alpha token followed by a TEN_TO_NINETYNINE token. While the parser rule identifierLeadingCharacter does allow the Alpha token, the identifierCharacter rule cannot match a TEN_TO_NINETYNINE token.

The input 10 will always produce a TEN_TO_NINETYNINE token rather than two Digit tokens, because the former matches more of the input and lexer rules are greedy.

这篇关于Antlr4 语法歧义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆