ANTLR C语法不识别点符号

ANTLR C grammar not recognizing dot notation

我们正在使用 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 from the ANTLR Grammars repository. That being said, we adjusted it to handle #include statements and it can be seen here。我们添加的是这两个解析器和这两个词法分析器:

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

includedLibExpression
    : IncludedHeaderDirective
    ;

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

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

然后为了使用新的解析器,我们将以下内容添加到 translationUnit。更令人困惑的是,如果 translationUnit 中带有 includeExpression 的行被注释掉,我们仍然会得到错误。

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 ',' '}'
;

让我百思不得其解的是,点号和箭头号相继出现,却只识别箭头号。

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

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

此模式匹配字符串 this.hello。因此,当词法分析器到达输入的第 2 行时,它可以应用 Identifier 规则来匹配 this 或应用 IncludeHeaderDirective 规则来匹配 this.hello。由于后者是较长的匹配,因此根据最大 munch 规则选择它。

因为 IncludedHeaderDirective 不是一个有效的表达式,你会得到你做的错误。为了匹配 postfixExpression '.' Identifier 规则,this.hello 必须标记为 Identifier, '.', Identifier,但 IncludedHeaderDirective 规则的存在阻止了这种情况。