2017-01-02 2 views
3

같은 문법을 허용 키워드를 구축하는 방법이 데모 코드Antlr4 식별자

label: 
var id 
let id = 10 
goto label 

입니다. 그러나 antlr에서 이것을하는 것이 매우 어려워 보입니다.

AFAIK, antlr이 토큰 let과 일치하면 절대 id 토큰으로 대체되지 않습니다. 그래서 ANTLR 것이 내가 토큰 일치하고 문제를 제어 할 수 있고, ANTLR 허용 predicate 비록

LET_TOKEN : 
VAR_TOKEN <missing ID_TOKEN>VAR_TOKEN 
LET_TOKEN <missing ID_TOKEN>VAR_TOKEN = 10 

을 볼 수 있습니다. 문법이이

grammar Demo; 
options { 
    language = Go; 
} 
@parser::members{ 
    var _need = map[string]bool{} 
    func skip(name string,v bool){ 
     _need[name] = !v 
     fmt.Println("SKIP",name,v) 
    } 
    func need(name string)bool{ 
     fmt.Println("NEED",name,_need[name]) 
     return _need[name] 
    } 
} 

[email protected]{skip("inst",false)}: (line? NL)* EOF; 
line 
    : VAR ID 
    | LET ID EQ? Integer 
    ; 

NL: '\n'; 
VAR: {need("inst")}? 'var' {skip("inst",true)}; 
LET: {need("inst")}? 'let' {skip("inst",true)}; 
EQ: '='; 

ID: ([a-zA-Z] [a-zA-Z0-9]*); 
Integer: [0-9]+; 

WS: [ \t] -> skip; 

이렇게 끔찍해 보입니다.

그러나이 말뚝에 쉽게, pegjs

Expression = (Line? _ '\n')* ; 

Line 
    = 'var' _ ID 
/'let' _ ID _ "=" _ Integer 

Integer "integer" 
    = [0-9]+ { return parseInt(text(), 10); } 

ID = [a-zA-Z] [a-zA-Z0-9]* 

_ "whitespace" 
    = [ \t]* 

이 테스트 실제로 peggojavacc에 이런 짓을.

내 질문은 antlr4.6에서 이러한 문법을 ​​처리하는 방법입니다. antlr4.6 목표에 대해 너무 흥분했지만 문법에 맞지 않는 도구를 선택하는 것 같습니다.

답변

6

가장 간단한 방법은 식별자에 대한 파서 규칙을 정의하는 것입니다 :

id: ID | VAR | LET; 

VAR: 'var'; 
LET: 'let'; 
ID: [a-zA-Z] [a-zA-Z0-9]*; 

그리고 파서 규칙에 id 대신 ID를 사용합니다.

다른 방법은 키워드에 식별자 ID을 사용하고 명확성을 위해 술어를 사용하는 것입니다. 하지만 읽기 쉽지 않으므로 대신 첫 번째 방법을 사용합니다.