2015-09-23 5 views
1

В настоящее время, я только определенные простые правила в ANTLR4:ANTLR4 несовпадающими ввода '' ожидая

// Recognizer Rules 

program : (class_dcl)+ EOF; 
class_dcl: 'class' ID ('extends' ID)? '{' class_body '}'; 
class_body: (const_dcl|var_dcl|method_dcl)*; 
const_dcl: ('static')? 'final' PRIMITIVE_TYPE ID '=' expr ';'; 
var_dcl: ('static')? id_list ':' type ';'; 
method_dcl: PRIMITIVE_TYPE ('static')? ID '(' para_list ')' block_stm; 
para_list: (para_dcl (';' para_dcl)*)?; 
para_dcl: id_list ':' PRIMITIVE_TYPE; 
block_stm: '{' '}'; 
expr: <assoc=right> expr '=' expr | expr1; 
expr1: term ('<' | '>' | '<=' | '>=' | '==' | '!=') term | term; 
term: ('+'|'-') term | term ('*'|'/') term | term ('+'|'-') term | fact; 
fact: INTLIT | FLOATLIT | BOOLLIT | ID | '(' expr ')'; 
type: PRIMITIVE_TYPE ('[' INTLIT ']')?; 
id_list: ID (',' ID)*; 

// Lexer Rules 

KEYWORD: PRIMITIVE_TYPE | BOOLLIT | 'class' | 'extends' | 'if' | 'then' | 'else' 
    | 'null' | 'break' | 'continue' | 'while' | 'return' | 'self' | 'final' 
    | 'static' | 'new' | 'do'; 
SEPARATOR: '[' | ']' | '{' | '}' | '(' | ')' | ';' | ':' | '.' | ','; 
OPERATOR: '^' | 'new' | '=' | UNA_OPERATOR | BIN_OPERATOR; 
UNA_OPERATOR: '!'; 
BIN_OPERATOR: '+' | '-' | '*' | '\\' | '/' | '%' | '>' | '>=' | '<' | '<=' 
    | '==' | '<>' | '&&' | '||' | ':='; 
PRIMITIVE_TYPE: 'integer' | 'float' | 'bool' | 'string' | 'void'; 
BOOLLIT: 'true' | 'false'; 
FLOATLIT: [0-9]+ ((('.'[0-9]* (('E'|'e')('+'|'-')?[0-9]+)?))|(('E'|'e')('+'|'-')? [0-9]+)); 
INTLIT: [0-9]+; 
STRINGLIT: '"' ('\\'[bfrnt\\"]|~[\r\t\n\\"])* '"'; 
ILLEGAL_ESC: '"' (('\\'[bfrnt\\"]|~[\n\\"]))* ('\\'(~[bfrnt\\"])) 
    {if (true) throw new bkool.parser.IllegalEscape(getText());}; 
UNCLOSED_STRING: '"'('\\'[bfrnt\\"]|~[\r\t\n\\"])* 
    {if (true) throw new bkool.parser.UncloseString(getText());}; 
COMMENT: (BLOCK_COMMENT|LINE_COMMENT) -> skip; 
BLOCK_COMMENT: '(''*'(('*')?(~')'))*'*'')'; 
LINE_COMMENT: '#' (~[\n])* ('\n'|EOF); 
ID: [a-zA-z_]+ [a-zA-z_0-9]* ; 

WS: [ \t\r\n]+ -> skip ; 
ERROR_TOKEN: . {if (true) throw new bkool.parser.ErrorToken(getText());}; 

Я открыл дерево синтаксического разбора, и попытался тест:

class abc 
{ 
final integer x=1; 
} 

Он вернулся ошибки:

BKOOL::program:3:8: mismatched input 'integer' expecting PRIMITIVE_TYPE 
BKOOL::program:3:17: mismatched input '=' expecting {':', ','} 

У меня все еще нет причин. Не могли бы вы помочь мне, почему он не распознал правила и токены, как я ожидал?

ответ

2

Правила Lexer являются исключительными. Самый длинный выигрыш, а тай-брейк - это грамматический порядок.

В вашем случае; integer - KEYWORD вместо PRIMITIVE_TYPE.

Что вы должны сделать здесь:

  • сделать один отчетливого маркера каждого ключевым слова вместо всех выделяющегося KEYWORD правила.
  • Turn PRIMITIVE_TYPE в правило синтаксического анализа
  • То же для операторов

Прямо сейчас, ваш пример:

class abc 
{ 
final integer x=1; 
} 

конвертируется в лексемы, такие как:
classID{finalKEYWORDID=INTLIT;}

Это связано с неявным набором символов, так как вы использовали определения, такие как 'class' в правилах вашего парсера. Они преобразуются в анонимные токены, такие как T_001 : 'class';, которые получают наивысший приоритет.

Если бы это было не так, то вы бы в конечном итоге с:
KEYWORDIDSEPARATORKEYWORDKEYWORDIDOPERATORINTLIT;SEPARATOR

И это ... не совсем легко разобрать ;-)
Вот почему я говорю вам правильно разбить свои жетоны.

+0

спасибо! – necroface

+0

Чтобы избежать новой темы, я редактирую свой вопрос для еще более сложного и запутанного вопроса. – necroface

+0

Не делайте этого, это противоречит стандартам SO. Пожалуйста, верните свой вопрос в предыдущую версию и опубликуйте этот вопрос в качестве нового вопроса. –