2017-01-02 13 views
3

Это демонстрационный кодAntlr4 как построить грамматику разрешенные ключевые слова в качестве идентификатора

label: 
var id 
let id = 10 
goto label 

Если разрешено ключевое слово в качестве идентификатора будет

let: 
var var 
let var = 10 
goto let 

Это абсолютно легально код. Но это очень сложно сделать в antlr.

AFAIK, Если antlr соответствует маркеру let, никогда не будет возвращаться к токену id. поэтому для ANTLR он будет видеть

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

хотя и Antlr позволило predicate, я должен контролировать когда-либо лексемы матч и проблематичной. грамматика станет

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]* 

Я на самом деле сделал это в peggo и javacc.

Мой вопрос заключается в том, как обращаться с этими грамматиками в antlr4.6, я был так в восторге от цели antlr4.6 go, но, кажется, я выбираю неправильный инструмент для своей грамматики?

ответ

6

Самый простой способ определить правила синтаксического анализа для идентификаторов:

id: ID | VAR | LET; 

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

И затем использовать id вместо ID в правилах синтаксического анализа.

Другой способ - использовать ID для идентификаторов и ключевых слов и использовать предикаты для значений. Но это менее читаемо, поэтому вместо этого я бы использовал первый способ.