Я пытаюсь обернуть голову вокруг PEG, вводя простые грамматики в PEG.js площадку .
Пример 1:
"abcdef1234567ghijklmn8901opqrs"
Желаемый вывод: ["abcdef", "1234567",
"ghijklmn", "8901", "opqrs"]
Фактический вывод: ["abcdef", ["1234567", ["ghijklmn", ["8901", ["opqrs", ""]] ]]]
Этот пример в значительной степени работает, но можно ли заставить PEG.js не вкладывать результирующий массив в миллион уровней? Я предполагаю, что хитрость заключается в том, чтобы где-то использовать concat ()
вместо join ()
, но я не могу найти это место.
start
= Text
Text
= Numbers Text
/ Characters Text
/ EOF
Numbers
= numbers: [0-9]+ {return numbers.join("")}
Characters
= text: [a-z]+ {return text.join("")}
EOF
= !.
Пример 2:
Та же проблема и код как в Примере 1, но измените правило «Символы» на следующее, которое, как я ожидал, даст тот же результат.
Characters
= text: (!Numbers .)+ {return text.join("")}
В результате вы получите:
[",a,b,c,d,e,f", ["1234567", [",g,h,i,j,k,l,m,n", ["8901", [",o,p,q,r,s", ""]]]]]
Почему я получаю все эти пустые совпадения?
Пример 3:
Последний вопрос. Это не работает вообще. Как я могу заставить это работать? А для бонусных баллов есть какие-то указатели на эффективность? Например, мне следует избегать рекурсии, если это возможно?
Буду также признателен за ссылку на хороший учебник по PEG. Я прочитал ( http://www.codeproject.com/KB/recipes/grammar_support_1.aspx ), но, как вы можете видеть, мне нужна дополнительная помощь ...
'abcdefghijklmnop "qrstuvwxyz" abcdefg'
["abcdefghijklmnop", "qrstuvwxyz",
"abcdefg"]
"abcdefghijklmnop \" qrstuvwxyz \ "abcdefg"
start
= Words
Words
= Quote
/ Text
/ EOF
Quote
= quote: ('"' .* '"') Words {return quote.join("")}
Text
= text: (!Quote . Words) {return text.join("")}
EOF
= !.