Мы используем 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 грамматика из ANTLR Grammars хранилища .При этом мы настроили его для обработки #include
операторов, и это можно увидеть здесь .Мы добавили эти два парсера и эти два лексера:
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 ',' '}'
;
Что меня действительно удивляет, так это тот факт, что обозначения точек и обозначения стрелок располагаются одна за другой, но распознается только обозначение стрелок.