2016-06-02 6 views
1

다음 ANTLR 문법을 감안할 때 :ANTLR : 예기치 않은 문자

SET "example 

ANTLR 다음과 같은 오류를 제공합니다 :

tokens 
{ 
    SET; 
    UNKNOWN; 
    LIST; 
} 


statement : SET_KEYWORD list = value_list -> ^(SET $list) 
      | UNKNOWN_KEYWORD -> ^(UNKNOWN); 

value_list : element += value (COMMA_KEYWORD element += value)* -> ^(LIST $element+); 

value : STRING_KEYWORD; 


SET_KEYWORD : 'SET'; 

UNKNOWN_KEYWORD : .; 

fragment STRING_KEYWORD : '"' ('a'..'z' | 'A'..'Z')* '"'; 

하나 (이중 따옴표를 닫지 않고 예) 다음 텍스트를 구문 분석

TEST(1) : lexer error 1 : 
     Unexpected character at offset 12, (end of input). 
     This indicates a poorly specified lexer RULE 
     or unterminated input element such as: "STRING["] 
     The lexer was matching from line 1, offset 3, which 
     looks like this: 
       "example 

UNKNOWN_KEYWORD가 이러한 유형의 문제를 따라 잡을 것이라고 생각할 것입니다. 앞에서 언급 한 오류 메시지가 더 이상 표시되지 않도록 문법을 어떻게 수정할 수 있습니까?

답변

0

홈페이지 버그

문법의 주요 버그 렉서 규칙으로 UNKNOWN_KEYWORDSTRING_KEYWORD을 설명한다. 렉서가 있기 때문에 귀하의 파서는 SET "example 입력과 일치하지 않습니다 following : 렉서는 UNKNOWN_KEYWORD으로 일치하고 STRING_KEYWORD의 시작으로, 그것은이 규칙이 있기 때문에 STRING_KEYWORD로 입력을 일치하기로 결정 될 수있는 "을 충족

Lexer looks for the first longest matching rule. In other words, if multiple rules match the input, the longest one is selected.

UNKNOWN_KEYWORD보다 길어집니다.

따라서 이러한 규칙을 구문 분석기 규칙으로 다시 작성하는 것이 좋습니다. 렉서가 더 간단한 토큰과 일치하도록하십시오.

  • 규칙에 AST 연산자를 사용하는 출력 유형을 설명하기위한 options 블록을 누락 :

    기타 버그이 외에도

    는 문법의 다른 버그가 있습니다.

  • statement 규칙에서 UNKNOWN_KEYWORD 이후에 누락 된 +. +이 없으면 해당 진술 문이 SET_KEYWORD value_list 또는 단일 문자라고 말합니다.
  • 줄 바꿈 및 공백에 대한 누락 규칙.
  • statement 규칙 끝에 EOF이 누락되었습니다. SET "abc"bla-bla-bla과 같은 입력은 AST (SET (LIST "abc"))SET_KEYWORD value_list으로 구문 분석됩니다. 즉 bla-bla-blaEOF없이 무시됩니다.
  • COMMA_KEYWORD 규칙에 대한 설명이 없습니다.
  • 조각 규칙으로 STRING_KEYWORD을 기술하십시오. 규칙이 조각 인 경우 파서는이 규칙에 설명 된 토큰을 얻지 못합니다.

AST 문제

당신이 파서 규칙과 같은 UNKNOWN_KEYWORDSTRING_KEYWORD를 다시 작성하고 다음 AST 얻을 SET "example" 입력 파서을 시도하는 경우 :

(SET (LIST " e x a m p l e ")) 

, 즉 "example"은 AST의 전체 노드가 아닙니다. 일반적으로 AST의 한 노드가 하나의 토큰을 구성하기 때문에 모든 문자에 대해 별도의 노드가 있습니다.그러나이 (ANTLR 3 Runtime 3.5.2 API 참조) 가상 토큰을 생성하고 CommonTree 클래스의 생성자를 호출을 통해 노드를 작성하여 해결할 수 있습니다

value : st = string_keyword -> {new CommonTree(new CommonToken(KEYWORD, $st.text))}; 

결과 문법

그래서 같이 보일 수 있습니다 문법은 다음과 같습니다

options { 
    output=AST; 
    ASTLabelType=CommonTree; 
} 

tokens { 
    SET; 
    UNKNOWN; 
    LIST; 
    KEYWORD; 
} 

statement : ((SET_KEYWORD value_list)=> SET_KEYWORD list= value_list NEWLINE -> ^(SET $list) 
      | unknown_keyword+ NEWLINE -> ^(UNKNOWN) 
      ) 
      EOF; 

value_list : element += value (COMMA_KEYWORD element += value)* -> ^(LIST $element+); 

value : st= string_keyword -> {new CommonTree(new CommonToken(KEYWORD,$st.text))}; 

NEWLINE:'\r'? '\n' ; 
WS: (' '|'\t'|'\n'|'\r')+ {skip();}; 
COMMA_KEYWORD: ','; 
SET_KEYWORD : 'SET'; 
QUOTES:'"'; 
LETTER:('a'..'z' | 'A'..'Z'); 
ANY:.; 
string_keyword : QUOTES LETTER* QUOTES ; 
unknown_keyword : SET_KEYWORD|QUOTES|LETTER|COMMA_KEYWORD|ANY; 
관련 문제