Декларация, согласованная до назначения - PullRequest
0 голосов
/ 22 сентября 2018

Я создаю синтаксический анализатор для языка программирования, который я строю, и столкнулся с проблемой: ANTLR, похоже, намеревается не соответствовать объявлениям переменных.
Вот грамматика:

// Define a grammar called simc
grammar simc;

//Parser Rules
program : statement+ ;
statement : declaration | assignment | ( expression SEMICOLON ) ;
expression          : LEFTPAREN expression RIGHTPAREN                 #parenthesisExp
                    //Math
                    | <assoc=right>  expression '^' expression        #powerExp
                    | expression (ASTERISK|SLASH) expression          #mulDivExp
                    | expression (PLUS|MINUS) expression              #addSubExp
                    //Bool Operations
                    | expression EQUALITY expression                  #equalCompExp
                    | expression NONEQUALITY expression               #notequalCompExp
                    | expression GREATERTHAN expression               #greaterCompExp
                    | expression LESSTHAN expression                  #lessCompExp
                    | expression GREATERTHANOREQUALTO expression      #greaterorequalCompExp
                    | expression LESSTHANOREQUALTO expression         #lessorequalCompExp                   
                    //Any value that isn't an expression itself
                    | value                                           #valueExp
                    ;
value : constvalue | functioncall | variable ;
functioncall : IDENTIFIER LEFTPAREN expression? ( COMMA expression )? RIGHTPAREN ;
declaration : typelabel variable EQUALS expression SEMICOLON ;
assignment : variable EQUALS expression SEMICOLON ;
constvalue : intvalue | floatvalue | stringvalue | boolvalue ;
typelabel : INTLABEL | FLOATLABEL | STRINGLABEL | BOOLLABEL ;
variable : IDENTIFIER ;
intvalue : INTVALUE ;
floatvalue : FLOATVALUE ;
stringvalue : STRINGVALUE ;
boolvalue : BOOLVALUE ;

//Lexer Rules
IDENTIFIER : [a-zA-Z][a-zA-Z0-9]* ;
LEFTPAREN : '(' ;
RIGHTPAREN : ')' ;
INTLABEL : I N T ;
FLOATLABEL : F L O A T ;
STRINGLABEL : S T R I N G ;
BOOLLABEL : B O O L ;
INTVALUE : [0-9]+ ;
FLOATVALUE : [0-9]+ ( PERIOD [0-9]+ F? | F ) ;
STRINGVALUE : QUOTE ( '\\"' | . )*? QUOTE ;
BOOLVALUE : ( T R U E ) | ( F A L S E ) ;
SEMICOLON : ';' ;
ASTERISK : '*' ;
SLASH : '/' ;
PLUS : '+' ;
MINUS : '-' ;
EQUALS : '=' ;
EQUALITY : '==' ;
NONEQUALITY : '!=' ;
GREATERTHAN : '>' ;
LESSTHAN : '<' ;
GREATERTHANOREQUALTO : '>=' ;
LESSTHANOREQUALTO : '<=' ;
COMMA : ',' ;
PERIOD : '.' ;
QUOTE : '"' ;
fragment A : [aA] ; // match either an 'a' or 'A'
fragment B : [bB] ;
fragment C : [cC] ;
fragment D : [dD] ;
fragment E : [eE] ;
fragment F : [fF] ;
fragment G : [gG] ;
fragment H : [hH] ;
fragment I : [iI] ;
fragment J : [jJ] ;
fragment K : [kK] ;
fragment L : [lL] ;
fragment M : [mM] ;
fragment N : [nN] ;
fragment O : [oO] ;
fragment P : [pP] ;
fragment Q : [qQ] ;
fragment R : [rR] ;
fragment S : [sS] ;
fragment T : [tT] ;
fragment U : [uU] ;
fragment V : [vV] ;
fragment W : [wW] ;
fragment X : [xX] ;
fragment Y : [yY] ;
fragment Z : [zZ] ;
WS : [ \r\t\n]+ -> skip ;
COMMENT : ( ( '/' '/' .*? ( '\r'|'\t'|'\n' ) ) | '/*' .*? '*/' ) -> skip ;

Грамматика должна, если я не ошибаюсь, соответствовать коду int a = 5; как объявлению переменной.Вместо этого я получаю пустой оператор (который я не понимаю, как это конкретное событие возможно), оператор, помеченный как неправильный, содержащий текст int (в моем тестировании он работал только для допустимых имен типов) и правильное назначение.Насколько я понимаю, декларации должны быть найдены до назначения, верно?Почему это так, и как я могу это исправить?

1 Ответ

0 голосов
/ 22 сентября 2018

Если вы посмотрите на токены, сгенерированные для вашего ввода, вы увидите, что он видит int как IDENTIFIER, а не INTLABEL.Это происходит потому, что вы определили IDENTIFIER до INTLABEL в своей грамматике, и когда несколько правил лексера могут совпадать с одним и тем же количеством ввода, оно будет использовать то, которое стоит первым в грамматике.Поэтому вы всегда должны определять правило идентификатора после ключевых слов.

...