【问题标题】:ANTLR4 Mismatch in simple grammarANTLR4 简单语法不匹配
【发布时间】:2014-08-19 07:41:15
【问题描述】:

我正在使用最新版本的 Antlr (4.3) 来解析这个简单的源文件。我正在使用 Visual Studio 加载项,但这与我的问题无关。

源文件:

OBJECT Codeunit 80 Sales-Post
{
  OBJECT-PROPERTIES
  {
    Date=11/12/10;
    Time=12:00:00;
    Version List=NAVW16.00.10,NAVBE6.00.01;
  }
}

这应该很容易解析,但我在解析时不断收到 2 个错误:

line 1:16 mismatched input '80' expecting DOCUMENT_ID
line 5:4 mismatched input 'Date' expecting {DOCUMENT_PROPERTY_ID, '}'}

完整的语法:

grammar Cal;

/*
 * Parser Rules
 */
document
    : document_header OPEN_BRACE document_content CLOSE_BRACE
    ;

document_header
    : OBJECT_DEFINITION DOCUMENT_TYPE DOCUMENT_ID DOCUMENT_NAME
    ;

document_content
    : document_properties
    ;

document_properties
    : OBJECT_PROPERTIES OPEN_BRACE document_property* CLOSE_BRACE
    ;

document_property
    : DOCUMENT_PROPERTY_ID EQ DOCUMENT_PROPERTY_VALUE LINE_TERM
    ;


/*
 * Lexer Rules
 */
OBJECT_PROPERTIES
    : 'OBJECT-PROPERTIES'
    ;

OBJECT_DEFINITION
    : 'OBJECT'
    ;

DOCUMENT_TYPE
    : 'Codeunit'
    | 'Table'
    ;

DOCUMENT_PROPERTY_VALUE
    : ([0-9a-zA-Z]|'_'|'-'|'.'|'/'|','|':')+
    ;

DOCUMENT_PROPERTY_ID
    : 'Date'
    | 'Time'
    | 'Version List'
    ;

DOCUMENT_ID
    : [0-9]+
    ;

DOCUMENT_NAME
    : ID
    ;

OPEN_BRACE
    : '{'
    ;

CLOSE_BRACE
    : '}'
    ;

LINE_TERM
    : ';'
    ;

EQ
    : '='
    ;

ID
    : ([a-zA-Z]|'_'|'-')+
    ;

INT
    : [0-9]+
    ;

WS
    : [ \t]+ -> channel(HIDDEN)
    ;

NEWLINE
    :'\r'? '\n' -> channel(HIDDEN)
    ;

这是令牌流的输出(令牌用''包围:

<OBJECT> < > <Codeunit> < > <80> < > <Sales-Post> <
> <{> <
> <  > <OBJECT-PROPERTIES> <
> <  > <{> <
> <    > <Date> <=> <11/12/10> <;> <
> <    > <Time> <=> <12:00:00> <;> <
> <    > <Version List> <=> <NAVW16.00.10,NAVBE6.00.01> <;> <
> <  > <}> <
> <}> <<EOF>

【问题讨论】:

    标签: c# antlr grammar antlr4


    【解决方案1】:

    在 ANTLR 中,当两个词法分析器规则可以匹配相同的标记(相同长度)时,首先出现的规则获胜。

    80 可以匹配DOCUMENT_ID,也可以匹配DOCUMENT_PROPERTY_VALUEINT,所以只需在此处重新排列这些规则即可。

    DOCUMENT_PROPERTY_IDDOCUMENT_PROPERTY_VALUE 之下也有同样的问题(两者都可以匹配Date)。

    我建议您将DOCUMENT_PROPERTY_VALUE 放在WS 的上方:最具体的规则(即关键字)在前,更广泛的规则在后。

    您还必须摆脱DOCUMENT_IDINT,因为它们具有相同的定义。其中之一永远不会匹配。您似乎没有在解析器中使用INT,所以只需删除该规则即可。

    【讨论】:

    • 我还建议在DOCUMENT_IDDOCUMENT_NAME 中添加语义含义应该在解析器规则中完成,而不是在词法分析器规则中。根据经验:如果您无法确定10DOCUMENT_ID 还是普通INT,请不要在完全不了解上下文的词法分析器中做出决定,并等待决定直到解析时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2015-04-19
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    相关资源
    最近更新 更多