Схема является недетерминированной , когда есть две ветви, начинающиеся с одного и того же элемента - так что вы не можете сказать, какую ветвь выбрать, не заглядывая в будущее после этого элемента. Простой пример - ab|ac
- когда вы видите a
, вы не знаете, какую ветку взять. Для циклов «ветвь» - это повторение цикла или продолжение после него. Примером этого является a*a
- когда вы находитесь в цикле и читаете a
, вы не знаете, повторить ли цикл или продолжить.
Глядя на вашу примерную схему, представьте, что она только что проанализировала <till>
, и теперь ей нужно проанализировать <from>
. Вы можете проанализировать его с помощью <from><till>
loop или с финальным <from>
. Вы не можете сказать, какую ветку использовать, просто взглянув на это <from>
. Вы можете сказать только с дальнейшим прогнозом.
Плохие новости: я думаю, что ваша примерная схема очень редкая, что невозможно выразить детерминистически!
Вот XML-документы, которые вы хотите принять (я использую одну букву для каждого элемента, где a
= <from>...</from>
и b
= <to>...</to>
:
*empty*
a
ab
aba
abab
ababa
ababab
...
... вы поняли идею. Проблема в том, что любая буква может быть последней буквой в последовательности или , она может быть частью цикла. Нет никакого способа определить, каким он будет, кроме как заглянуть в следующее письмо. Поскольку «детерминистический» означает, что вы не делаете этого заблаговременно (по определению), нужный вам язык не может быть выражен детерминистически.
Упрощая вашу схему, она использует подход, аналогичный (ab)*a?
- но обе ветви начинаются с a
. Другой подход - a(ba)*b?
- теперь обе ветви начинаются с b
. Мы не можем победить!
Технически, набор всех документов, которые принимает схема, называется языком этой схемы . Если не существует детерминированной схемы, способной выразить язык, язык называется «однозначным».
Теоретическое обсуждение см. В серии статей Бруггемана-Кляйна (например, Детерминированные регулярные языки и Однозначные регулярные языки ).
Она включает формальный тест для однозначных языков.