Регулярная аппроксимация КС-языков — различия между версиями
(→Алгоритм преобразования грамматики в конечный автомат) |
(→Идея алгоритма) |
||
Строка 25: | Строка 25: | ||
Пусть, <tex> P = \{N_1,N_2,...,N_K\} </tex> разбиение <tex> N^*</tex> на <tex> k </tex> дизъюнктных множеств взаимно рекурсивных терминалов, | Пусть, <tex> P = \{N_1,N_2,...,N_K\} </tex> разбиение <tex> N^*</tex> на <tex> k </tex> дизъюнктных множеств взаимно рекурсивных терминалов, | ||
<tex> N_1 \cup N_2 \cup ... \cup N_k = N^* \land \forall i N_i \neq \emptyset </tex>. | <tex> N_1 \cup N_2 \cup ... \cup N_k = N^* \land \forall i N_i \neq \emptyset </tex>. | ||
− | Ввведем функцию <tex> | + | Ввведем функцию <tex> getTheTypeOfMutualRecursiveSet(N_i): P \rightarrow \{left, right, self, cycle\} </tex>: |
'''function''' IsLeftType(<tex>N_i</tex>) | '''function''' IsLeftType(<tex>N_i</tex>) | ||
'''return''' <tex> \exists (A \Rightarrow \alpha B \beta) \in P[ A \in N_i \land B \in N_i \land \alpha \neq \varepsilon ]</tex> | '''return''' <tex> \exists (A \Rightarrow \alpha B \beta) \in P[ A \in N_i \land B \in N_i \land \alpha \neq \varepsilon ]</tex> | ||
Строка 33: | Строка 33: | ||
− | '''function''' | + | '''function''' getTheTypeOfMutualRecursiveSet (<tex>N_i</tex>): |
− | '''if''' !IsLeftType(<tex>N_i</tex>) && | + | '''if''' !IsLeftType(<tex>N_i</tex>) && IsRightType(<tex>N_i</tex>) |
return left; | return left; | ||
− | '''if''' IsLeftType(<tex>N_i</tex>) && ! | + | '''if''' IsLeftType(<tex>N_i</tex>) && !IsRightType(<tex>N_i</tex>) |
return right; | return right; | ||
− | '''if''' (IsLeftType(<tex>N_i</tex>) && | + | '''if''' (IsLeftType(<tex>N_i</tex>) && IsRightType(<tex>N_i</tex>) |
return self; | return self; | ||
− | '''if''' !IsLeftType(<tex>N_i</tex>) && ! | + | '''if''' !IsLeftType(<tex>N_i</tex>) && !IsRightType(<tex>N_i</tex>) |
return cyclic; | return cyclic; | ||
− | Заметим, что <tex> \forall i </tex> <tex> | + | Заметим, что <tex> \forall i </tex> <tex>getTheTypeOfMutualRecursiveSet(N_i) \neq self </tex>, т.к грамматика не самоприменима.<br \> |
В основе алгоритма будет рекурсивный обход грамматики во все стороны. Спускаемся по грамматике до тех пор не приходим в нетерминал или символ алфавита: | В основе алгоритма будет рекурсивный обход грамматики во все стороны. Спускаемся по грамматике до тех пор не приходим в нетерминал или символ алфавита: | ||
# символ алфавит или <tex> \varepsilon </tex> {{---}} добавляем новое правило в автомат | # символ алфавит или <tex> \varepsilon </tex> {{---}} добавляем новое правило в автомат |
Версия 15:15, 20 января 2014
Содержание
Определения
Определение: |
Контекстно-свободная грамматика называется самоприменимой (англ. self-embeded), если , . |
Определение: |
Нетерминал | в грамматике называется рекурсивным (англ. recursive), если .
Определение: |
Нетерминалы | в грамматике называются взаимно рекурсивными (англ. mutual recursive), если .
Алгоритм преобразования грамматики в конечный автомат
Лемма: |
Не самоприменимая контекстно-свободная грамматика генерирует регулярный язык. |
Доказательство: |
В качестве конструктивного доказательства, мы приведем алгоритм построения конечного автомата по грамматике. Для желающих, приведем ссылку на формальное доказательство. |
Идея алгоритма
Пусть,
множество рекурсивных терминалов из . Пусть, разбиение на дизъюнктных множеств взаимно рекурсивных терминалов, . Ввведем функцию :function IsLeftType() return function IsRightType( ) return
function getTheTypeOfMutualRecursiveSet (): if !IsLeftType( ) && IsRightType( ) return left; if IsLeftType( ) && !IsRightType( ) return right; if (IsLeftType( ) && IsRightType( ) return self; if !IsLeftType( ) && !IsRightType( ) return cyclic;
Заметим, что
В основе алгоритма будет рекурсивный обход грамматики во все стороны. Спускаемся по грамматике до тех пор не приходим в нетерминал или символ алфавита:
- символ алфавит или — добавляем новое правило в автомат
- нерекурсивный нетерминал — запускаемся от всех правых частей правил, который терминал порождает
- рекурсивный нетерминал — в зависимости от типа рекурсивного нетерминала, продолжаем рекурсию (будет ясно из пседокода)
Псевдокод
— множество состояний ДКА. — множество переходов ДКА. — множество допускающих состояний.
function createFA(G) //s = createState f = createState return makeFA (s,S,f) function makeFA (q0,a,q1) if a == || a // пришли в лист дерева разбора return if a == where q = createState makeFA ( ) makeFA ( ) return if exist where foreach b in = createState if recursive( ) == left foreach C in where makeFA ( ) foreach C,D in where makeFA ( ) else // рекурсивный нетерминал rihgt или self foreach C in where makeFA ( ) foreach C,D in where makeFA ( ) return foreach p in where p == makeFA ( )
Аппроксимации самоприменимой грамматики
В данном разделе покажем методы апроксимации самоприменимой свободно-контекстной грамматики НФХ.
к регулярной грамматике. Для удобства будем считать, что грамматика представлена вRTN аппроксимация
Построим, по данной грамматике аппроксимирующий ее конечный автомат.
- Для каждого нетерминала в грамматике, создадим новый конечный автомат , добавим в него два состояния и .
- Для каждого правила грамматике , введм новые состояния в автомат этого нетерминала , а также добавим новые правила перехода в : .
- Таким образом мы построили множество конечных автоматов = для каждого нетерминала . Теперь объединим все в один автомат. Объединим все состоянии автоматов из в множество . Скопируем все переходы каждого автомата из в . Далее для каждого перехода вида , вместо него добавим два новых перехода: .
MT аппроксимация
Построим, по данной самоприменимой кс грамматике
, регулярную грамматику .- Для каждого нетерминала из , добавим нетерминалы и в .
- Для каждого правила
(Если , тогда добавим правило ). , где . Добавим в нетерминалы и следуюшие правила: .
В итоге правоконтекстная грамматика, эквивалентная конечному автомату, который задает регулярный язык.
—Пример