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
规则的存在阻止了这种情况。
我们正在使用 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
规则的存在阻止了这种情况。