Как лучше всего анализировать отдельный список запятых в грамматике PEG

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

(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]

Это почему? (новичок в грамматике здесь)


person Leon Starr    schedule 12.06.2019    source источник


Ответы (1)


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

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

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

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

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

ввод: (1, 4)

  • ест '('
  • проверьте, есть ли какие-то цифры?
  • check some_digits - first condition:
    • eats '1'
    • ест ', '
    • check some_digits - first condition:
      • eats '4'
      • не ест ', '
    • check some_digits - second condition:
      • eats '4'
      • преуспевает
    • преуспевает
  • ест ')'
  • преуспевает

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

person James Wasson    schedule 12.06.2019
comment
Кстати, для второй строки это тоже работает: some_digits = digit (', ' some_digits)? - person James Wasson; 12.06.2019
comment
@LeonStarr О, ты хочешь, чтобы я ответил на вторую часть твоего поста? Извините я забыл - person James Wasson; 12.06.2019
comment
Не нужно, Джеймс, ваш ответ прояснил для меня логику синтаксического анализа PEG (что было моей настоящей проблемой). Но спасибо за вопрос. - person Leon Starr; 13.06.2019