2016-07-25 98 views
0

我正在爲腳本語言編寫解析器,並使用antlr 4.5.3作爲目的。Antlr4完全忽略了換行符,只有一點

grammar VSE; 

chunk 
    : block* EOF 
    ; 

block 
    : var '=' exp 
    | functioncall 
    ; 

var 
    : NAME 
    | var '[' exp ']' 
    | var '.' var 
    ; 

exp 
    : number 
    | string 
    | var 
    | functioncall 
    | <assoc=right> exp exp //concat 
    ; 

functioncall 
    : NAME '(' (exp)? (',' exp)* ')' 
    | var '.' functioncall 
    ; 


string 
    : '"' (~('"' | '\\' | '\r' | '\n') | '\\' ('"' | '\\'))* '"' 
    ; 

NAME 
    : [a-zA-Z_][a-zA-Z_0-9]* 
    ; 

number 
    : INT | HEX | FLOAT 
    ; 

INT 
    : Digit+ 
    ; 

HEX 
    : '0' [xX] [0-9a-fA-F]+ 
    ; 

FLOAT 
    : Digit* '.' Digit+ 
    ; 

Digit 
    : [0-9] 
    ; 

WS 
    : [ \t\u000C\r\n]+ -> skip 
    ; 

然而,在測試它,我發現像var = something然後在下一行某些函數調用一個變量賦值導致CONCAT聲明。 (我的concat語句是一個變量,後面跟着另一個像var = var1 var2)我知道antlr跳過了所有新行以支持行連續,但是我想補充一點,如果在兩個exp之間有一條新行,它會將它們視爲兩個單獨的塊而不是concat語句。即

var = var2 
functioncall(var) 

這些應該是兩個單獨的塊而不是concat語句。 有沒有辦法做到這一點?

回答

0

以下規則適合您嗎?

block 
    : var '=' exp NEW_LINE 
    | functioncall NEW_LINE 
    ; 

NEW_LINE: '\r'? '\n' 

WS 
    : [ \t]+ -> skip 
    ; 

在另一種情況下,您應該使用Semantic Predicates或非常不清楚的語法。

+0

這工作正常,如果我只使用賦值和函數調用。但是,如果它打破了所有其他事情的延續。有沒有辦法在不添加可選NEW_LINE的情況下執行此操作? – Crimson7