2014-09-01 5 views
1

문법을 테스트하기 위해 this ANTLR 3 grammar과 ANTLRWorks를 사용하고 있습니다.ANTRL 3 문법이 입력 소스 코드의 일부를 생략했습니다.

하지만 입력 텍스트의 일부가 생략 된 이유를 알 수 없습니다.

이 문법을 다시 작성하고 AST/CST에서 소스 파일 (입력)의 모든 요소 (lparen, keywords, semicolon, ..)를 표시하고 싶습니다.

모든 것을 시도했지만 성공하지 못했습니다. ANTLR 경험이있는 사람이 나를 도울 수 있습니까?

enter image description here

구문 분석 트리 :

parse tree

+3

먼저 모든 토큰을 표시하려면 AST가 아닌 구문 분석 트리를 표시해야합니다. 정의에 따라이 정보가 부족합니다. 그렇다면 ANTLR v4 [ECMAScript grammar] (https://github.com/antlr/grammars-v4/tree/master/ecmascript)를 사용해 보시지 않겠습니까? –

+0

답장을 보내 주셔서 감사합니다. 그러나이 프로젝트에 ANTLR v3을 사용해야하고, 구문 분석 트리 (CST)를 만들어야하기 때문에 문제가 있습니다. 따라서 파스 트리가 많은 도움이되지 않습니다. AST에서 모든 소스 요소 (lparen, 키워드, 점 등)를 가져야합니다. –

+2

제 생각에 * CST *는 구문 분석 트리 *와 동의어입니다. 당신이 무엇을하려고하는지 모르겠지만 * AST * 수준이 아닌이 추상 수준에서 작업해야 할 것 같습니다. –

답변

1

나는 semic 규칙에 범위를 좁힐 관리했습니다 :

/* 
This rule handles semicolons reported by the lexer and situations where the ECMA 3 specification states there should be semicolons automaticly inserted. 
The auto semicolons are not actually inserted but this rule behaves as if they were. 

In the following situations an ECMA 3 parser should auto insert absent but grammaticly required semicolons: 
- the current token is a right brace 
- the current token is the end of file (EOF) token 
- there is at least one end of line (EOL) token between the current token and the previous token. 

The RBRACE is handled by matching it but not consuming it. 
The EOF needs no further handling because it is not consumed by default. 
The EOL situation is handled by promoting the EOL or MultiLineComment with an EOL present from off channel to on channel 
and thus making it parseable instead of handling it as white space. This promoting is done in the action promoteEOL. 
*/ 
semic 
@init 
{ 
    // Mark current position so we can unconsume a RBRACE. 
    int marker = input.mark(); 
    // Promote EOL if appropriate 
    promoteEOL(retval); 
} 
    : SEMIC 
    | EOF 
    | RBRACE { input.rewind(marker); } 
    | EOL | MultiLineComment // (with EOL in it) 
    ; 

그래서, EVIL 세미콜론 삽입 공격을 다시!

나는 정말로 확신하지 못하지만,이 mark/rewind 호출이 동기화되지 않고 있다고 생각합니다. 실제 일치를 위해 분기 선택 에 대한 규칙을 입력하면 @init 블록이 실행됩니다. 실제로 많은 표시가 있지만 청소하지는 않습니다. 하지만 왜 그렇게 파스 트리를 뒤죽박죽인지 모르겠다.

semic 
@init 
{ 
    // Promote EOL if appropriate 
    promoteEOL(retval); 
} 
    : SEMIC 
    | EOF 
    | { int pos = input.index(); } RBRACE { input.seek(pos); } 
    | EOL | MultiLineComment // (with EOL in it) 
    ; 

훨씬 간단하고 mark/rewind 메커니즘을 사용하지 않습니다

어쨌든, 여기에 동일한 규칙의 작업 버전입니다.

하지만 catch가 있습니다. 구문 분석 트리의 semic 규칙은 닫는 중괄호 앞에 세미콜론을 삽입 할 경우 자식 노드가 }입니다. i-- 뒤에 세미콜론을 제거한 다음 결과를 확인하십시오. 이를 감지하고 코드에서 처리해야합니다. semic; 토큰을 포함하거나 EOL (이 시점에서 세미콜론이 자동으로 삽입되었음을 의미)을 포함해야합니다.

+0

ANTLR 4에서 '되감기'를 제거한 것을 매우 기쁘게 생각합니다. –