2012-10-05 96 views
5

我試圖寫一個簡單的語法爲將匹配像這樣PEG.js的PEG.js結束:麻煩的輸入

some text; 
arbitrary other text that can also have µnicode; different expression; 
let's escape the \; semicolon, and \not recognized escapes are not a problem; 
possibly last expression not ending with semicolon 

所以基本上這些都是用分號隔開一些文本。我的簡化語法如下:

start 
= flow:Flow 

Flow 
= instructions:Instruction* 

Instruction 
= Empty/Text 

TextCharacter 
= "\\;"/
. 

Text 
= text:TextCharacter+ ';' {return text.join('')} 

Empty 
= Semicolon 

Semicolon "semicolon" 
= ';' 

的問題是,如果我把比分號以外的任何輸入,我得到:

SyntaxError: Expected ";", "\\;" or any character but end of input found. 

如何解決這個問題?我讀過PEG.js無法匹配輸入的結尾。

+4

FWIW,您可以將輸入的結尾與'!.' – ebohlman

回答

8

你有(至少)2個問題:

TextCharacter不應與任何字符(該.)。它應該匹配任何字符,除了反斜槓和分號,也應該與一個轉義字符:

TextCharacter 
= [^\\;] 
/"\\" . 

的第二個問題是,你的語法強制要求你輸入一個分號結束(但您輸入的內容不以;結束)。

如何這樣的事情,而不是:

start 
= instructions 

instructions 
= instruction (";" instruction)* ";"? 

instruction 
= chars:char+ {return chars.join("").trim();} 

char 
= [^\\;] 
/"\\" c:. {return ""+c;} 

這將如下解析您的輸入:

[ 
    "some text", 
    [ 
     [ 
     ";", 
     "arbitrary other text that can also have µnicode" 
     ], 
     [ 
     ";", 
     "different expression" 
     ], 
     [ 
     ";", 
     "let's escape the ; semicolon, and not recognized escapes are not a problem" 
     ], 
     [ 
     ";", 
     "possibly last expression not ending with semicolon" 
     ] 
    ] 
] 

注意,尾隨分號現在是可選的。