2012-10-05 32 views
5

Próbuję napisać prosty grammer dla PEG.js które odpowiadają mniej więcej tak:Kłopoty z PEG.js koniec wejścia

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 

Więc w zasadzie są to niektóre teksty oddzielone średnikami. Moja uproszczona grammer wygląda następująco:

start 
= flow:Flow 

Flow 
= instructions:Instruction* 

Instruction 
= Empty/Text 

TextCharacter 
= "\\;"/
. 

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

Empty 
= Semicolon 

Semicolon "semicolon" 
= ';' 

Problemem jest to, że jeśli mogę umieścić coś innego niż średnik na wejściu, otrzymuję:

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

Jak rozwiązać ten problem? Czytałem, że PEG.js nie jest w stanie dopasować końca wejścia.

+4

FWIW, możesz dopasować koniec wejścia za pomocą '! .' – ebohlman

Odpowiedz

8

mieć (co najmniej) 2 problemy:

Twój TextCharacter nie powinien dopasować dowolny znak (The .). Należy dopasować dowolny znak z wyjątkiem backslashem i średnikiem lub powinien pasować zbiegłego charakter:

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

Drugim problemem jest to, że gramatyka mandaty swój wkład kończyć się średnikiem (ale Twój wkład robi nie kończy się na ;).

Jak o coś takiego zamiast:

start 
= instructions 

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

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

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

które analizowania swój wkład w następujący sposób:

[ 
    "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" 
     ] 
    ] 
] 

nocie że Kończący średnik jest opcjonalny teraz.