Как лучше разобрать запятую отдельный список в грамматике PEG - PullRequest
3 голосов
/ 12 июня 2019

Я пытаюсь разобрать список через запятую. Чтобы упростить, я просто использую цифры. Эти выражения будут действительны:

(1, 4, 3)

()

(4)

Я могу придумать два способа сделать это, и мне интересно, почему именно неудачный пример не работает. Я считаю, что это правильный BNF, но я не могу заставить его работать как PEG. Кто-нибудь может объяснить, почему именно? Я пытаюсь лучше понять логику разбора PEG.

Я тестирую с помощью генератора парсеров интернет-браузера здесь: https://pegjs.org/online

Это не работает:

list = '(' some_digits? ')'
some_digits = digit / ', ' some_digits
digit = [0-9]

(на самом деле, он анализирует нормально и любит () или (1), но не распознает (1, 2)

Но это работает:

list = '(' some_digits? ')'
some_digits = digit another_digit*
another_digit = ', ' digit
digit = [0-9]

Почему это? (Грамматика новичок здесь)

1 Ответ

1 голос
/ 12 июня 2019

Прикольный вопрос и после того, как в течение нескольких секунд покопались в их документах, я обнаружил, что символ / означает:

Попробуйте сопоставить первое выражение, если не удалось, попробуйте второй и т. д. Вернуть результат совпадения первого успешно согласованное выражение. Если ни одно выражение не соответствует, рассмотрите соответствие не удалось.

Итак, это привело меня к решению:

list = '(' some_digits? ')'
some_digits = digit ', ' some_digits / digit
digit = [0-9]

Причина, по которой это работает:

вход: (1, 4)

  • ест '('
  • проверь, есть ли цифры?
  • check some_digits - первое условие:
    • ест '1'
    • ест ','
    • check some_digits - первое условие:
      • ест '4'
      • не ест ','
    • check some_digits - второе условие:
      • ест '4'
      • успешно
    • успешно
  • ест ')'
  • успешно

если вы измените порядок условий some_digits, с которыми сталкивается первое число, оно будет съедено digit и рекурсия не произойдет. Тогда он выдает ошибку, потому что ')' нет.

...