Отказывается ли движок Peg.js после просмотра, как это делают регулярные выражения? - PullRequest
0 голосов
/ 19 октября 2018

В соответствии с регулярной -expressions.info о обходных путях, движок отступает после просмотра:

Давайте еще раз заглянем внутрь, чтобы убедиться, что вы понимаете последствия поиска.Давайте применим q (? = U) i для выхода.Взгляд в будущее теперь положительный, за ним следует еще один жетон.Снова q соответствует q, а u соответствует u.Опять же, совпадение с предвкушением должно быть отброшено, поэтому двигатель отступает от i в строке к u.Ожидание было успешным, поэтому двигатель продолжает с i.Но я не могу соответствовать тебе.Так что эта попытка матча не удалась.Все оставшиеся попытки также терпят неудачу, потому что в строке больше нет q.

Однако в Peg.js он SEEMS , как будто двигатель все еще движется, прошел &или !, так что на самом деле это не предвидение в том же смысле, что и регулярные выражения, а решение о потреблении, и нет никакого шага назад, и, следовательно, нет истинного взгляда в будущее.

Так ли это?

(Если это так, то определенный анализ даже невозможен, например этот ?)

1 Ответ

0 голосов
/ 19 октября 2018

Lookahead работает аналогично тому, как это происходит в движке регулярных выражений.

Этот запрос не соответствует, потому что следующая буква должна быть 'u', а не 'i'.

word = 'q' &'u' 'i' 't'

Этот запрос успешно выполняется:

word = 'q' &'u' 'u' 'i' 't'

Этот запрос успешно выполняется:

word = 'q' 'u' 'i' 't'

Что касается вашего примера, попробуйте что-то в этом духе, вам вообще не нужно использовать lookaheads:

expression
    = termPair ( _ delimiter _ termPair )*

termPair
    = term ('.' term)? ' ' term ('.' term)?

term "term"
    = $([a-z0-9]+)

delimiter "delimiter"
    = "."

_ "whitespace"
    = [ \t\n\r]+

РЕДАКТИРОВАТЬ : добавлен еще один пример для комментариев ниже.

expression
    = first:term rest:delimTerm* { return [first].concat(rest); }

delimTerm
    = delimiter t:term { return t; }

term "term"
    = $((!delimiter [a-z0-9. ])+)

delimiter "delimiter"
    = _ "." _

_ "whitespace"
    = [ \t\n\r]+

РЕДАКТИРОВАТЬ : добавлено дополнительное объяснение термина выражения.

Я попытаюсь немного разобрать термин «правило» $((!delimiter [a-z0-9. ])+).

$() преобразует все внутри в один текстовый узел, например [].join('').

«Один»символ "термина" - это любой символ [a-z0-9. ], если бы мы хотели упростить его, мы могли бы вместо этого сказать ..Перед сопоставлением символа мы хотим посмотреть на delimiter, если мы найдем delimiter, мы прекращаем сопоставлять этот символ.Поскольку нам нужно несколько символов, мы делаем все это несколько раз с помощью +.

. В PEG-парсерах это обычная идиома, чтобы двигаться вперед таким образом.Я узнал идею из документации treetop для сопоставления строки.

...