2012-06-12 4 views
2

У меня есть следующая грамматика, и я хочу совместить строку «{name1, name2}». Мне просто нужны списки имен/интергеров с хотя бы одним элементом. Однако я получаю ошибку:
линии 1: 6 нет реальной альтернативы в характере «»
линии 1:11 жизнеспособной альтернативы в характере «}»
линии 1: 7 несовпадающего ввод «имя» ожидая SIMPLE_VAR_TYPEОшибка символа пропущенных символов Antlr

Я бы предположил, что пробелы и т. Д. Игнорируются ... Также интересно, что ошибка не возникает при вводе «{name1, name2}» (без пробела после «,»). Heres мой gramar

grammar NusmvInput; 
options { 
    language = Java; 
} 
@header { 
    package secltlmc.grammar; 
} 
@lexer::header { 
    package secltlmc.grammar; 
} 
specification : 
    SIMPLE_VAR_TYPE EOF 
    ;  
INTEGER 
    : ('0'..'9')+ 
    ; 
SIMPLE_VAR_TYPE 
    : ('{' (NAME | INTEGER) (',' (NAME | INTEGER))* '}' ) 
    ; 
NAME 
    : ('A'..'Z' | 'a'..'z') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '$' | '#' | '-')* 
    ; 
WS 
    : (' ' | '\t' | '\n' | '\r')+ {$channel = HIDDEN;} 
    ; 

И это мой код тестирования

package secltlmc; 
public class Main { 
    public static void main(String[] args) throws 
      IOException, RecognitionException { 
     CharStream stream = new ANTLRStringStream("{name1, name2}"); 
     NusmvInputLexer lexer = new NusmvInputLexer(stream); 
     CommonTokenStream tokenStream = new CommonTokenStream(lexer); 
     NusmvInputParser parser = new NusmvInputParser(tokenStream); 
     parser.specification(); 
    } 
} 

Спасибо за вашу помощь.

ответ

2

Проблема в том, что вы пытаетесь разобрать SIMPLE_VAR_TYPE с помощью lexer, т. Е. Вы пытаетесь сделать это одним токеном. На самом деле, похоже, что вы хотите создать многотоновый ток, так как вы хотите, чтобы пробелы были перенаправлены на скрытый канал через WS.

Вы должны изменить SIMPLE_VAR_TYPE из правила lexer в правило анализатора, изменив его начальную букву (или, еще лучше, полное имя) на нижний регистр.

specification : 
    simple_var_type EOF 
    ;  

simple_var_type 
    : ('{' (NAME | INTEGER) (',' (NAME | INTEGER))* '}' ) 
    ; 
+0

@HeinrichOdy Я понимаю, что правила лексера может используйте другие правила lexer только явно. Правила Parser неявно используют все правила lexer, потому что правила парсера имеют более высокий уровень. Парсер вызывает лексер для следующего токена, лексер передает 'WS' на скрытый канал и переходит к следующему токену. Вы также правы, что вы можете использовать 'WS' внутри правил lexer явно. – dasblinkenlight

+0

Sry, за удаление моего собственного комментария ... Поднял ваш ответ, объяснив мне, что в прожекторах прожектора токенов не работает со скрытыми жетонами, спасибо. –

1

Согласно определению из SIMPLE_VAR_TYPE указывает следующее выражение:

  • Открыть {
  • следуют один из NAME или INTEGER
  • follwoed нулем или более из следующего:
    • запятой (,), а затем один из NAME или INTEGER
  • с последующим закрытием }

Нигде не позволяют пробельных на входе (ни NAME, ни INTEGER не позволяет ее), так что вы получите сообщение об ошибке, когда вы указываете один

Try:

SIMPLE_VAR_TYPE 
: ('{' (NAME | INTEGER) (WS* ',' WS* (NAME | INTEGER))* '}' ) 
; 
+0

Возможно, я также должен добавить WS к '{' WS * ... WS * '}', но я вижу, куда вы направляетесь, спасибо :) –

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