2013-07-13 2 views
1

Я написал следующую грамматику. Я хочу написать выражения x + 2; х/2; ...Предупреждение о решении ANTLR

grammar HASKELL; 

options { 
    language = Java; 
} 

program 
    : statment+ 
    ; 

statment 
    :declaration 
    | expression 
    ; 

declaration 
    : typeDecl 
    ; 

typeDecl 
    :numType 
    |listType 
    ; 

type 
    : 'num' 
    | 'list'  
    ; 


numType 
    : type IDENT '=' INTEGER ';' 
    ; 


listType 
    :type IDENT '=' '[' INTEGER* ']' ';' 
    ; 

term      
    : IDENT 
    | '(' expression ')' 
    | INTEGER 
    ; 

negation 
    : 'not'* term 
    ; 

unary 
    : ('+' | '-')* negation 
    ; 

mult 
    : unary (('*' | '/' | 'mod') unary) * 
    ; 

add 
    : mult (('+' | '-') mult)* 
    ; 

relation   
    : add (('=' |'/='|'<'|'<='|'>'|'>=') add)* 
    ; 

expression 
    : relation (('and' | 'or') relation)* 
    ; 

MULTILINE_COMMENT : '/*' .* '*/' {$channel = HIDDEN;} ; 
fragment LETTER : ('a'..'z' | 'A'..'Z') ; 
fragment DIGIT : '0'..'9'; 
INTEGER : DIGIT+ ; 
IDENT : LETTER (LETTER | DIGIT)*; 
WS : (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN;}; 
COMMENT : '//' .* ('\n'|'\r') {$channel = HIDDEN;}; 

, который производит следующее предупреждение:

(200): Decision can match input such as "'+'..'-' IDENT" using multiple 
     alternatives: 1,2 As a result, alternative(s) 2 were disabled for 
     that input HASKELL.g Assignment2/src/com/assignment2/antlr3x/first  
     line 59 DLTK Problem 

Я не могу увидеть путаницу, вызванную оных. Я попытался удалить ('+' | '-') * под унарным, и это сработало. Но не хотите исключать такие вещи, как x + (- 2). Любые идеи, как это сделать, не снимая («+» | «-») * Thanks

+0

Я имел в виду один в ошибке «множественная альтернатива» – user2262955

+0

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

ответ

2

Ваша грамматика неоднозначна из этих правил:

program 
    : statment+ 
    ; 

statment 
    : declaration 
    | expression 
    ; 

То есть: вы позволяете для нескольких expression s без разделительный токен, например, ; или разрыв строки. Из-за этого, ввод так:

1+2 

может быть проанализирован в нескольких разборов:

statment 
    | 
    +--> expression --> INTEGER (1) 
    | 
    +--> expression --> unary (+2) 

или как это:

statment 
    | 
    +--> expression --> add (1+2) 

Вы можете проверить это путем удаления + из вашего program правило:

program 
    : statment 
    ; 

, который вызывает предупреждение.

Смежные вопросы