我们正在使用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 ',' '}'
;
真正使我感到困惑的是,点符号和箭头符号是一个接一个的事实,但是只有箭头符号可以识别。
答案 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
规则的存在阻止了这一点。