Простые вопросы анализа с использованием PEG.js

Я пытаюсь обернуть голову вокруг 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
  = !.

21
задан hippietrail 11 August 2014 в 09:42
поделиться