Более чем достаточно «Всегда получится»? [RAKU] - PullRequest
5 голосов
/ 04 марта 2020

В документации по грамматике в разделе:

Утверждение "Всегда успешно"

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

use v6.d;

grammar Digifier {
    rule TOP { [ <.succ> <digit>+ ]+ }
    token succ   { <?> }
    token digit { <[0..9]> }
}

class Letters {
    has @!numbers;

    method digit ($/) { @!numbers.tail ~= <a b c d e f g h i j>[$/]; say '---> ' ~ @!numbers }
    method succ  ($/) { @!numbers.push: '!'; say @!numbers }
    method TOP   ($/) { make @!numbers[^(*-1)] }
}

say 'FINAL ====> ' ~ Digifier.parse('123 456 789', actions => Letters.new).made;

Результат следующий:

[!]
---> !b
---> !bc
---> !bcd
[!bcd !]
---> !bcd !e
---> !bcd !ef
---> !bcd !efg
[!bcd !efg !]
---> !bcd !efg !h
---> !bcd !efg !hi
---> !bcd !efg !hij
[!bcd !efg !hij !]

FINAL ====> !bcd !efg !hij

Я ожидал только 3 нажатия в таблице @! числа, но я получил 4. Я озадачен о необходимости исключения последнего значения таблицы @! numbers в методе "TOP".

Да, я знаю, что код дает правильный результат, но почему?

Где последний Утверждение "всегда добиваться успеха"?

1 Ответ

6 голосов
/ 04 марта 2020

Количественно определенная группа, например, [ A B ]+, фактически все oop, неоднократно пытается соответствовать A, и, если совпадает, пытается сопоставить B.

Если это не бесконечно l oop - в этом случае ваша программа будет зависать - она ​​в конечном итоге будет соответствовать N раз и затем продолжится. Если A всегда совпадает, но ваша программа не зависает, то это должно означать, что B в конечном итоге потерпел неудачу. Если это так, то A гарантированно совпадет еще раз, чем B.

В вашем коде A равно <.succ>, что уменьшает до <?>, что всегда совпадает. Есть 4 попытки и, таким образом, A совпадений 4 раз. В отличие от этого B, то есть <digit>+, терпит неудачу с четвертой попытки, поэтому соответствует только 3 раз.

...