2012-04-11 1 views
1

필자는 파이썬 (ID 목록의 숫자 목록을 허용 할 수있는 문법)을 사용하여 ANTLR에서 작은 문법을 만들었지 만 December 12 1965과 같은 문자열을 입력하면 ANTLR이 파일에서 실행되어 표시됩니다내 antlr 문법이이 입력을 제대로 구문 분석하는 이유는 무엇입니까?

grammar ParserLang; 

options { 
    language=Python; 
} 

@header { 
import sys 
import antlr3 

from ParserLangLexer import ParserLangLexer 
} 

@main { 
def main(argv, otherArg=None): 
    char_stream = antlr3.ANTLRInputStream(open(sys.argv[1],'r')) 
    lexer = ParserLangLexer(char_stream) 

    tokens = CommonTokenStream(lexer) 
    parser = ParserLangParser(tokens); 

    rule = parser.entry_rule() 
} 

program  : idList EOF 
      | integerList EOF 
      ; 

idList  : ID whitespace idList 
      | ID 
      ; 

integerList : INTEGER whitespace integerList 
      | INTEGER 
      ; 

whitespace : (WHITESPACE | COMMENT) +; 

ID   : LETTER (DIGIT | LETTER)*; 
INTEGER  : (NONZERO_DIGIT DIGIT*) | ZERO ; 
WHITESPACE : ('\t' | ' ' | '\r' | '\n'| '\u000C')+ { $channel = HIDDEN; } ; 
COMMENT  : ('/*' .* '*/') | ('//' .* '\n') { $channel = HIDDEN; } ; 

fragment ZERO   : '0' ; 
fragment DIGIT   : '0' .. '9'; 
fragment NONZERO_DIGIT : '1' .. '9'; 
fragment LETTER  : 'a' .. 'z' | 'A' .. 'Z'; 

오전 내가 뭔가 잘못하고 다음 코드 (그리고 나는 @main를 통해 박혀되어 사용하고 파이썬 코드의 모든)와 나 오류하지?

EDIT : 동일한 문법 입력으로 ANTLRWorks를 사용할 때 NoViableAltException이 발생합니다. 코드를 통해 오류를 어떻게 얻을 수 있습니까?

답변

2

재현 할 수 없습니다. 문법 오류 (rule = parser.entry_rule() : rule = parser.program()이어야 함)를 수정 한 후 입력에서 렉서 및 파서를 생성하고 입력 파일을 "December 12 1965" (파일의 입력 또는 일반 문자열)로 구문 분석하면 다음 오류가 발생합니다 : 그건 idList의 시작이 될 수 있기 때문에 생소 할 수 있습니다

line 1:0 no viable alternative at input u'December' 

.

  • WHITESPACECOMMENTHIDDEN 채널에 배치되어, 적어도이 아닌 변경하지 않고 (파서 규칙 그에 사용할 수 없습니다 : 사실은 문법이 하나 이상의 오류 및 개선 할 수있는 작은 일을 포함한다 파서가 토큰을 읽는 채널 ...);
  • 입력 끝의 COMMENT 즉, \n이 없으면 제대로 토큰되지 않습니다. 다음과 같이 한 줄 주석을 더 잘 정의하십시오 : '//' ~('\r' | '\n')*. 결국 후행 줄 바꿈은 결국 WHITESPACE 규칙에 의해 캡처됩니다.

파서 때문에 whitespace 규칙의 idList (또는 그 문제에 대한 integerList)와 일치 할 수 없기 때문에는 오류가 첫 번째 토큰 ('December')을 가리키는 생산된다.

grammar ParserLang; 

options { 
    language=Python; 
} 

@header { 
import sys 
import antlr3 

from ParserLangLexer import ParserLangLexer 
} 

@main { 
def main(argv, otherArg=None): 
    lexer = ParserLangLexer(antlr3.ANTLRStringStream('December 12 1965')) 
    parser = ParserLangParser(CommonTokenStream(lexer)) 
    parser.program() 
} 

program  : idList EOF 
      | integerList EOF 
      ; 

idList  : ID+ 
      ; 

integerList : INTEGER+ 
      ; 

ID   : LETTER (DIGIT | LETTER)*; 
INTEGER  : (NONZERO_DIGIT DIGIT*) | ZERO ; 
WHITESPACE : ('\t' | ' ' | '\r' | '\n'| '\u000C')+ { $channel = HIDDEN; } ; 
COMMENT  : ('/*' .* '*/' | '//' ~('\r' | '\n')*) { $channel = HIDDEN; } ; 

fragment ZERO   : '0' ; 
fragment DIGIT   : '0' .. '9'; 
fragment NONZERO_DIGIT : '1' .. '9'; 
fragment LETTER  : 'a' .. 'z' | 'A' .. 'Z'; 

또한 오류가 발생합니다 위의 문법에서 생성 된 파서를 실행 : 여기

는 (예상대로) 작동하는 문법이다

line 1:9 missing EOF at u'12' 

을하지만 예상된다 idList 후 파서는 EOF을 예상하지만 대신 '12'이 발생합니다.