ANTLR C语法无法识别点表示法

时间:2018-09-17 13:19:00

标签: c antlr antlr4

我们正在使用ANTLR来解析C,并且我们的许多代码都为结构添加了点符号。自从我写C以来已经有一段时间了,但是根据我的记忆,这两个语句是同义的:

void hello() {
    this->hello = "hello";
    this.hello = "hello";
}

ANTLR能够毫无问题地解析greeting->hello,但是,点符号会引发以下错误:

line 3:4 mismatched input 'this.hello' expecting '}'

如果我们像这样切换语句:

void hello() {
    this.hello = "hello";
    this->hello = "hello";
}

错误是:

line 2:4 mismatched input 'this.hello' expecting {'__extension__', '__builtin_va_arg', '__builtin_offsetof', '__m128', '__m128d', '__m128i', '__typeof__', '__inline__', '__stdcall', '__declspec', '__asm', '__attribute__', '__asm__', 'auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do', 'double', 'enum', 'extern', 'float', 'for', 'goto', 'if', 'inline', 'int', 'long', 'register', 'restrict', 'return', 'short', 'signed', 'sizeof', 'static', 'struct', 'switch', 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while', '_Alignas', '_Alignof', '_Atomic', '_Bool', '_Complex', '_Generic', '_Noreturn', '_Static_assert', '_Thread_local', '(', '{', '}', '+', '++', '-', '--', '*', '&', '&&', '!', '~', ';', Identifier, Constant, DigitSequence, StringLiteral}
line 3:8 no viable alternative at input 'this->'
line 4:0 extraneous input '}' expecting <EOF>

我们正在使用C grammar中的ANTLR Grammars repository。话虽如此,我们将其调整为处理#include条语句,可以看到here。我们添加的是这两个解析器和这两个词法分析器:

includeExpression
    : IncludeDirective includedLibExpression '"'
    | IncludeDirective includedLibExpression '>'
    ;

includedLibExpression
    : IncludedHeaderDirective
    ;

IncludeDirective
    : '#' Whitespace? 'include' Whitespace '"'
    | '#' Whitespace? 'include' Whitespace '<'
    ;

IncludedHeaderDirective
    : ('a'..'z' | 'A'..'Z' | '.' | '_' | '/')+
    ;

然后使用新的解析器,我们将以下内容添加到translationUnit中。为了使事情更加混乱,如果includeExpression中带有translationUnit的行被注释掉,我们仍然会收到错误消息。

translationUnit
    :   externalDeclaration
    |   translationUnit externalDeclaration
    |   includeExpression+?
    ;

应该采用的特定解析器是这样的:

postfixExpression
    :   primaryExpression
    |   postfixExpression '[' expression ']'
    |   postfixExpression '(' argumentExpressionList? ')'
    |   postfixExpression '.' Identifier
    |   postfixExpression '->' Identifier
    |   postfixExpression '++'
    |   postfixExpression '--'
    |   '(' typeName ')' '{' initializerList '}'
    |   '(' typeName ')' '{' initializerList ',' '}'
    |   '__extension__' '(' typeName ')' '{' initializerList '}'
    |   '__extension__' '(' typeName ')' '{' initializerList ',' '}'
;

真正使我感到困惑的是,点符号和箭头符号是一个接一个的事实,但是只有箭头符号可以识别。

1 个答案:

答案 0 :(得分:4)

您已将以下词法分析器规则添加到语法中:

<div id="button-container">
    Click a button to change this content<input id="which-language-btn" type="button" onclick="myTest1()" value="What language is this?">
</div>

此模式与字符串IncludedHeaderDirective : ('a'..'z' | 'A'..'Z' | '.' | '_' | '/')+ ; 相匹配。因此,当词法分析器到达您输入的第2行时,它可以应用this.hello规则来匹配Identifier,也可以应用this规则来匹配IncludeHeaderDirective。由于后者是较长的匹配项,因此将根据最大的规则进行选择。

由于this.hello不是有效的表达式,因此会出现错误。为了匹配IncludedHeaderDirective规则,postfixExpression '.' Identifier必须被标记为this.hello,但是Identifier, '.', Identifier规则的存在阻止了这一点。