Изменения

Перейти к: навигация, поиск

Алгоритм Эрли

2460 байт убрано, 20:23, 18 января 2016
Нет описания правки
{{Определение
|definition =
Пусть <tex>G = \langle N, \Sigma, P, S \rangle</tex> {{---}} [[Контекстно-свободные грамматики, вывод, лево- и правосторонний вывод, дерево разбора|контекстно-свободная]] грамматика и <tex>w = a_1 a_2 w_0 w_1 ... a_nw_{n-1}</tex> {{---}} входная цепочка из <tex>\Sigma^*</tex>.Объект вида <tex>[A \rightarrow \alpha \cdot \beta, i]</tex>, где <tex>A \rightarrow \alpha \beta </tex> — правило из <tex>P</tex> и <tex>0 \leqslant i \leqslant n</tex> — позиция в <tex>w</tex>, называется '''ситуацией''', относящейся к цепочке <tex>w</tex>, где '''<tex> \cdot </tex>''' {{---}} вспомогательный символ, который не явлется терминалом или нетерминалом ( <tex> \cdot \notin \Sigma \cup N</tex>).
}}
{{Определение
|definition =
'''Ситуации хранятся в множествах <tex>j</tex>-м списком ситуаций''' <tex>I_j</tex> для входной цепочки <tex>w = a_1 a_2 D_0,... a_n</tex>, где <tex>0 \leqslant j \leqslant D_{n-1}</tex>, называется множество называемых '''списками ситуаций '''. Причем наличие ситуации <tex>\lbrace [A \rightarrow \alpha \cdot \beta , i] \mid \alpha \Rightarrow^* a_{i+1} ... a_j; \exists \gamma, \delta : S \Rightarrow^* \gamma A \delta, \gamma \Rightarrow^* a_1...a_i \rbrace</tex>. То есть в <tex>\gamma \alpha j</tex> выводит часть -м списке ситуаций <tex>wD_j</tex> c первого по <tex>j</tex>-й символ.равносильно тому, что }} {{Лемма|statement = <tex>(\exists \alpha : [S \rightarrow \alpha \cdot, 0] delta \in I_n) \Leftrightarrow w Sigma \in Lcup N : ((G)</tex>.|proof = Поскольку <tex>S ' \Rightarrow^* \gamma S \delta</tex> (при <tex>\gamma = w_0...w_{i-1} A \delta = \varepsilon</tex>), из определения <tex>I_n</tex> получаем, что <tex>([S \rightarrow \alpha \cdot, 0] \in I_n) \Leftrightarrow (S \Rightarrow \alpha wedge A \Rightarrow^* a_1 w_i... a_n = ww_{j-1})</tex>.
}}
{{Определение
|definition =
Последовательность списков ситуаций <tex>I_0D_0, I_1D_1, .., I_nD_{n-1}</tex> называется <b>списком разбора</b> для входной цепочки <tex>w</tex>.
}}
== Алгоритм Эрли ==
Чтобы воспользоваться леммой, необходимо найти <tex>I_nD_n</tex> для <tex>w</tex>. Алгоритм Эрли является [[Динамическое программирование|динамическим алгоритмом]]: он последовательно строит список разбора, причём при построении <tex>I_jD_j</tex> используются <tex>I_0D_0, \ldots, I_D_{j}</tex> (то есть элементы списков с меньшими номерами и ситуации, содержащиеся в текущем списке на данный момент).
Алгоритм основывается на следующих трёх правилах:
# Если <tex>[A \rightarrow \alpha \cdot a_w_{j} \beta, i] \in I_D_{j-1}</tex> (где <tex>a_jw_j</tex> — <tex>j</tex>-ый символ строки), то <tex>[A \rightarrow \alpha a_w_{j} \cdot \beta, i] \in I_jD_j</tex>.# Если <tex>[B \rightarrow \eta \cdot , ki] \in I_jD_j</tex> и <tex>[A \rightarrow \alpha \cdot B \beta, ik] \in I_{k}D_i</tex>, то <tex>[A \rightarrow \alpha B \cdot \beta, ik] \in I_jD_j</tex>.# Если <tex>[B A \rightarrow \alpha \cdot A B \etabeta, ki] \in I_jD_{j} </tex> и <tex>(A B \rightarrow \betaeta) \in P</tex>, то <tex>[A B \rightarrow \cdot \betaeta, j] \in I_jD_{j}</tex>.
=== Псевдокод ===
Для простоты добавим новый стартовый вспомогательный нетерминал <tex>S'</tex> и правило <tex>(S' \rightarrow S)</tex>.
'''function''' <tex>\mathtt{earley}(G, w)</tex>:
<font color=green>// Инициализация </font>
<tex> D_{0} = \lbrace [S' \rightarrow \cdot S, 0] \rbrace </tex>
'''for''' <tex>i = 1</tex> '''to''' <tex>len(w) - 1</tex>
<tex>D_i</tex> = <tex>\varnothing </tex>
<font color=green>// Вычисление ситуаций </font>
'''for''' <tex>j = 0</tex> '''to''' <tex>len(w) - 1</tex>
<tex>\mathtt{scan}(D, j, G, w)</tex>
'''while''' <tex>D_j</tex> изменяется
<tex>\mathtt{complete}(D, j, G, w)</tex>
<tex>\mathtt{predict}(D, j, G, w)</tex>
<font color=green>// Результат </font>
'''if''' <tex>[S' \rightarrow S \cdot, 0] \in D_{len(w)} </tex>
'''return''' ''true''
'''else'''
'''return''' ''false''
<font color=green>// Первое правило </font> '''function''' <tex>I_0\mathtt{scan}(D, j, G, w)</tex> : '''if''' <tex>j</tex> == <tex>\lbrace 0</tex> '''return''' '''for''' <tex>[S' A \rightarrow \alpha \cdot Sa \beta, 0i] \rbracein D_{j - 1} </tex> '''if''' <tex>a</tex> == <tex>w_{j - 1}</tex> # Правило (0) — инициализация useful_loop(0) <tex>D_{j}</tex> <tex> \cup</tex>= <tex>[A \rightarrow \alpha \cdot a \beta, i]</tex>
<font color=green>// Второе правило </font> '''function''' <tex>\mathtt{complete}(D, j, G, w)</tex>: '''for ''' <tex>[B \rightarrow \eta \cdot, i] \in D_{j = 1..n} </tex> '''for ''' <tex>[A \rightarrow \alpha \cdot a_{j} B \beta, ik] \in I_D_{j-1i}</tex> <tex>I_jD_{j}</tex> &<tex> \cup;</tex>= <tex>\{ [A \rightarrow \alpha a_{j} B \cdot \beta, ik] \}</tex> # Правило (1) useful_loop(j)
function useful_loop(j): do for <texfont color=green>[B \rightarrow \eta \cdot , k] \in I_j// Третье правило </texfont> for '''function''' <tex>[A \rightarrow \alpha \cdot B \beta, i] \in I_mathtt{kpredict}(D, j, G, w)</tex>: '''for''' <tex>I_j</tex> &cup;= <tex>\lbrace [A \rightarrow \alpha B \cdot B \beta, i] \rbracein D_{j} </tex> # Правило (2) '''for ''' <tex>[(B \rightarrow \alpha \cdot A \eta, k] ) \in I_jP </tex> for <tex>\beta : (A \rightarrow \beta) \in PD_{j}</tex> <tex>I_j\cup</tex> &cup;= <tex>\lbrace [A B \rightarrow \cdot \betaeta, j] \rbrace</tex> # Правило (3) while на данной итерации какое-то множество изменилось
==Корректность алгоритма==
{{Теорема
|statement = Приведенный алгоритм правильно строит все списки ситуаций.То есть алгоритм поддерживает инвариант <tex> [A \rightarrow \alpha \cdot \beta, i] \in D_{j} \Longleftrightarrow \exists \delta \in \Sigma \cup N : ((S' \Rightarrow^* w_0...w_{i-1} A \delta) \wedge A \Rightarrow^* w_i...w_{j-1})</tex>
|proof =
=====Алгоритм не добавит в список ситуацию, которая ему не принадлежит:=====<b><tex>\Longrightarrow</tex></b><br/>
Докажем индукцией по исполнению алгоритма.<br/>
<u> ''База (инициализация) индукции: '' <tex/u>\alpha = \varepsilon \Rightarrow^* \varepsilon <br/tex> и <tex>[S' \Rightarrow^* rightarrow \gamma cdot S , 0] \delta in D_0</tex> при .<texbr/><u>\gamma = \delta = \varepsilon ''Индукционный переход:'' </texu>.<br/>Индукционный переход: пусть в Пусть предположение верно для всех списков ситуаций с номерами меньше <tex> I_{0},...,I_{j} </tex> нет лишних ситуаций. Пусть включаем Разберемся, в результате применения какого правила ситуация <tex>[A \rightarrow \alpha \cdot \beta, i] </tex> попала в <tex>I_D_{j}</tex>. Рассмотрим три случая:<br/>
1. Включаем по правилу <tex>(1)\mathtt{scan}</tex>.<br/>Тогда Это произошло, если <tex>\alpha = \alpha' a_a</tex>, <tex>a = w_{j-1} , </tex> и <tex> [A \rightarrow \alpha' \cdot a_{j} a \beta, i] \in I_D_{j-1}</tex>. <br/>По предположению индукции <tex>\alphaS' \Rightarrow^* a_{i+1}w_0...a_w_{ji-1} A \delta</tex> и существуют <tex>\gammaalpha'\Rightarrow^* w_i...w_{j-2}</tex> и <tex>\delta' ,<br/tex> такие, что тогда в силу <tex>S' \Rightarrow^* \gamma' A \delta', \gamma' \Rightarrow^* a_1...a_a = w_{ij-1} </tex>. Значит, получаем <tex> \alpha = \alpha' a_{j} a \Rightarrow^* a_w_i...w_{i+j-2}w_{j-1}= w_i...a_w_{j-1} </tex> и при .<br/>Таким образом условия: <tex>\gamma = \gammaS', \delta = Rightarrow^* w_0...w_{i-1} A \delta'</tex> и <tex>[A \rightarrow \alpha \cdot \beta, i] \in I_jRightarrow^* w_i...w_{j-1}</tex>выполняются.
2. Включаем по правилу <tex>(2)\mathtt{predict}</tex>.<br/>Тогда По построению: <tex>\alpha = \alpha' B varepsilon </tex> и <tex>i=j</tex>, [A что автоматически влечет второй пункт утверждения.<br/>Кроме того <tex>\rightarrow \alphaexists i' \cdot B \beta, le i] \in I_{k}</tex> и ситуация <tex> [B A' \rightarrow \eta alpha ' \cdotA \delta ', ki'] \in I_{j} D_i</tex>. По , из чего по предположению, индукции следует <tex>\alphaS' \Rightarrow^* a_{i+1}w_0...a_w_{ki'-1}, A' \eta \Rightarrow^* a_{k+1}...a_{j} delta ''</tex>, откуда и <tex>\alpha = \alpha' B \Rightarrow^*a_w_{i+1'}...a_w_{ji-1} </tex>. Кроме того<br/>Получаем, существуют что <tex>S' \gammaRightarrow^* w_0...w_{i'-1} A'</tex> и <tex>\delta'' </tex> такие, что значит <tex>S' \Rightarrow^* w_0...w_{i'-1} \gammaalpha' A \delta', \gammadelta '' = a_1...a_{i} </tex>. Значит, при следовательно <tex>S' \gamma = \gammaRightarrow^* w_0...w_{i'-1} w_{i', }...w_{i-1} A \delta = ' \delta''</tex> , в итоге <tex>[A S' \rightarrow \alpha \cdot \beta, Rightarrow^* w_0...w_{i] -1} A \in I_jdelta</tex>, что нам и требовалось.
3. Включаем по правилу <tex>(3)\mathtt{complete}</tex>.<br/>Тогда По построению: <tex>\alpha = \varepsilon, alpha ' A' </tex> и <tex>\exists i = j', \delta : [B A \rightarrow \alpha' \cdot A ' \etabeta, ki] \in I_D_{ji'}, \wedge [A ' \Rightarrow rightarrow \eta \cdot, i'] \betain D_j</tex>. По предположению <br/>Cледовательно <tex>\alpha = \alpha' A' \Rightarrow^* a_w_i...w_{k+i'-1} w_{i'}...a_w_{ij}</tex> и существуют <tex>\gamma'</tex> и <tex>\delta' </tex> такие, что <tex>S' \Rightarrow^* \gamma' B \delta', \gamma' \Rightarrow^* a_1= w_i...a_w_{kj-1} </tex>. Значит, при <tex>\gamma = \gamma' \alpha', \delta = \eta \delta' </tex> выполнено <tex> S' \Rightarrow^* \gamma A \delta</tex>что дает нам второй пункт утверждения, следовательно <tex>[A \rightarrow \alpha \cdot \betaа так как первый пункт следует из индукционного предположения, i] \in I_j</tex>все хорошо.
=====В каждый список попадут все ситуации, которые ему принадлежат:=====Для всех наборов <b><tex>\tau = \langle \alpha, \beta, \gamma, \delta, A, i , j \rangleLongleftarrow</tex> нужно доказать, что, если </b><br/>В обратную сторону будем доказывать индукцией по суммарной длине вывода <tex> S' \Rightarrow^* \gamma A \delta, \gamma \Rightarrow^* a_1w_0...a_w_{i-1}, (A \rightarrow \alpha \beta) \in P, \alpha \Rightarrow^* a_{i+1}delta</tex> из <tex>S'</tex> и <tex>w_i...a_w_{j-1}</tex>, то алгоритм добавит из <tex> [A \rightarrow \alpha \cdot \beta, i]</tex> в . После чего примениминдукцию по длине вывода <tex> I_w_i...w_{j-1}</tex> из <tex>\alpha</tex>.<br/>Рассмотрим три случая последнего символа <tex>\alpha</tex>:
''Рангом набора'' 1. <tex> \tau </tex> называется <tex> alpha = \tau_{Salpha '}(\tau) + 2(j + \tau_{\gamma}(\tau) + \tau_{\alpha}(\tau))a</tex>, где тогда <tex>\tau_a = w_{S'j-1}(\tau)</tex> — длина кратчайшего вывода и <tex>S\alpha ' \Rightarrow^* \gamma A \delta w_i...w_{j-2}</tex>, .<br/>По предположению индукции: <tex>[A \tau_{rightarrow \gamma}(alpha ' \tau)</tex> — длина кратчайшего вывода <tex>cdot a \gamma beta, i] \Rightarrow^* a_1...a_in D_{ij-1}</tex>, а отсюда по правилу <tex>\tau_mathtt{\alphascan}(\tau)</tex> — длина кратчайшего вывода получаем <tex>[A \rightarrow \alpha ' a \Rightarrow^* a_{cdot \beta, i+1}...a_] \in D_{j}</tex>.
Докажем утверждение индукцией по рангу набора2.<br/>База: если ранг <tex>\taualpha = \alpha ' B</tex> равен 0, то тогда <tex>\tau_exists i' : \alpha ' \Rightarrow^* w_i...w_{Si'-1} = \tau_wedge B ' \Rightarrow^* w_{\gammai'} = \tau_...w_{\alphaj-1} = j = i = 0</tex>. Значит, <tex>A = S'<br/tex>, Тогда имеем <tex>[A \rightarrow \alpha = ' a \gamma = cdot \delta = beta, i] \varepsilon in D_{j}</tex>, . Также можно записать <tex>S' \Rightarrow^* w_0...w_{i-1} A \beta = S delta</tex>. При инициализации такая ситуация , как <tex>[S' \rightarrow Rightarrow^* w_0...w_{i-1} w_i...w_{i'-1}B \beta \cdot S, 0]delta</tex> будет добавлена в ,а также <tex>I_0B \rightarrow \eta \wedge \eta \rightarrow w_{i'}...w_{j-1}</tex>.<br/>Индукционный переход:пусть ранг Применяя индукцию по второму параметру получим <tex>[B \taurightarrow \eta \cdot, i'] \in D_j</tex> равен , откуда по правилу <tex>r > 0\mathtt{complete}</tex>, пусть для всех наборов с меньшими рангами утверждение верно. Докажем для набора получаем <tex>[A \taurightarrow \alpha ' B \cdot \beta, i] \in D_{j}</tex>. Для этого рассмотрим три случая:
13. <tex>\alpha= \varepsilon </tex>, тогда <tex>i=j</tex> оканчивается терминалом.<br/>Тогда либо <tex>i = 0 \alpha wedge A = S \wedge \delta = \alpha' cvarepsilon</tex>. , что доказывает базу индукции,<br/>либо вывод можно записать в виде <tex>\alpha S' \Rightarrow^*a_w_0...w{i+'-1}w_{i'}...a_w{ji-1}</tex>, значит <tex>c A \delta ' \delta '' = a_w_0...w_{ji-1}A \delta</tex>. Рассмотрим набор для некоторого правила <tex>\tau(A' = \langle \alpharightarrow w_{i', a_}...w_{ji-1} \beta, \gamma, A \delta, A, i, j-1 ') \rangle in P</tex>. <br/>Отсюда по предположению индукции <tex>([A ' \rightarrow \alphacdot w_{i' a_}...w_{ji-1} A \beta) delta ', i'] \in PD_{i'}</tex>, следовательно ранг что после нескольких применений правила <tex>\tau'mathtt{scan}</tex> равен приводит к <tex>r - 2</tex>, так как <tex>\tau_{S[A'}(\tau) = \tau_rightarrow w_{Si'}(\tau'), \tau_...w_{\gammai-1}(\tau) = cdot A \tau_{\gamma}(\taudelta '), i'] \tau_in D_{\alphai}(\tau) = \tau_{\alpha}(\tau')</tex>. Значит, после чего по предположению правилу <tex>[A \rightarrow \alpha' \cdot a_{j} \beta, i] \in I_mathtt{j-1predict}</tex>, и получим <tex>[A \rightarrow \alpha \cdot \beta, i] </tex> будет добавлена в <tex>I_\in D_{j}</tex> по правилу <tex>(1)</tex>, что и требовалось.
2. <tex>\alpha</tex> оканчивается нетерминалом.<br/>
<tex>\alpha = \alpha' B</tex>. <tex>\alpha \Rightarrow^*a_{i+1}...a_{j}</tex>, значит <tex>\mathcal {9} k</tex> такое, что <tex>\alpha' \Rightarrow^*a_{i+1}...a_{k}, B \Rightarrow^* a_{k+1}...a_{j}</tex>.<br/>
Рассмотрим набор <tex>\tau' = \langle \alpha', B \beta, \gamma, \delta, A, i, k \rangle</tex>, его ранг меньше <tex>r</tex>, следовательно <tex>[A \rightarrow \alpha' \cdot B \beta, i] \in I_{k}</tex> по предположению.<br/>
Пусть <tex>B \Rightarrow \eta</tex> — первый шаг в кратчайшем выводе <tex>B \Rightarrow^* a_{k+1}...a_{j}</tex>. Рассмотрим набор <tex>\tau'' = \langle \eta, \varepsilon, \gamma \alpha', \beta \delta, B, k, j \rangle</tex>. <tex>S \Rightarrow^* \gamma A \delta \Rightarrow \gamma \alpha' B \beta \delta</tex>, следовательно <tex>\tau_{S'}(\tau'') \leqslant \tau_{S'}(\tau) + 1</tex>.<br> Пусть длина кратчайшего вывода <tex>\alpha' \Rightarrow^*a_{i+1}...a_{k}</tex> равна <tex>n_1</tex>, а длина кратчайшего вывода <tex> B \Rightarrow^* a_{k+1}...a_{j}</tex> равна <tex>n_2</tex>. Тогда <tex>\tau_{\alpha}(\tau) = n_1 + n_2</tex>. Так как <tex> B \Rightarrow \eta \Rightarrow^* a_{k+1}...a_{j}</tex>, то <tex>\tau_{\alpha}(\tau'') = n_2 - 1</tex>. Очевидно, что <tex>\tau_{\gamma}(\tau'') = \tau_{\gamma}(\tau) + n_1</tex>. Тогда ранг <tex>\tau''</tex> равен <tex>\tau_{S'}(\tau'') + 2(\tau_{\gamma}(\tau'') + \tau_{\alpha}(\tau'') + j) \leqslant \tau_{S'}(\tau) + 1 + 2(\tau_{\gamma}(\tau) + n_1 + n_2 - 1 + j)</tex> <tex>= \tau_{S'}(\tau) - 1 + 2(\tau_{\gamma}(\tau) + \tau_{\alpha}(\tau) + j) < r</tex>. Значит, по предположению для <tex>\tau''</tex>, <tex>[B \rightarrow \eta \cdot, k] \in I_{j}</tex>. Из того, что <tex>[A \rightarrow \alpha' \cdot B \beta, i] \in I_{k}</tex> и <tex>[B \rightarrow \eta \cdot, k] \in I_{j}</tex>, по правилу <tex>(2)</tex> <tex>[A \rightarrow \alpha \cdot \beta, i] </tex> будет добавлена в <tex>I_{j}</tex>.
 
3. <tex>\alpha = \varepsilon</tex>.<br/>
В этом случае <tex>i = j, \tau_{\alpha}(\tau) = 0, (A \rightarrow \beta) \in P</tex>.<br/>
<tex>\tau_{S'}(\tau) \neq 0</tex> т.к. иначе <tex> \gamma = \varepsilon</tex>, следовательно <tex> \tau_{\gamma}(\tau) = 0, i = 0 </tex>, откуда <tex> r = 0</tex>, но <tex>r > 0</tex>.
Т.к. <tex>\tau_{S'}(\tau) > 0</tex>, <tex> \exists B, \gamma', \gamma'', \delta', \delta'' : S' \Rightarrow^* \gamma' B \delta' \Rightarrow \gamma' \gamma'' A \delta' \delta''</tex>, где <tex>(B \rightarrow \gamma'' A \delta'') \in P</tex>. Рассмотрим набор <tex>\tau' = \langle \gamma'', A \delta'', \gamma', \delta', B, k, j \rangle</tex>, где <tex>k</tex> такое, что <tex>\gamma' \Rightarrow^* a_1...a_{k}, \gamma'' \Rightarrow^* a_{k+1}...a_{j}</tex>.
Пусть длина кратчайшего вывода <tex>\gamma' \Rightarrow^*a_{1}...a_{k}</tex> равна <tex>n_1</tex>, а длина кратчайшего вывода <tex> \gamma'' \Rightarrow^* a_{k+1}...a_{j}</tex> равна <tex>n_2</tex>.<br/>
Найдём ранг <tex>\tau'</tex>. <tex>\tau_{S'}(\tau') = \tau_{S'}(\tau) - 1, \tau_{\gamma}(\tau') = n_1, \tau_{\alpha}(\tau') = n_2</tex>. <tex>\tau_{\alpha}(\tau) = 0, \tau_{\gamma}(\tau) = n_1 + n_2</tex>, следовательно ранг <tex>\tau'</tex> равен <tex>r - 1</tex>. Значит, по предположению <tex>[B \rightarrow \gamma'' \cdot A \delta'', k] \in I_{j}</tex>, следовательно по правилу <tex>(3)</tex> <tex>[A \rightarrow \cdot \beta, i] </tex> будет добавлена в <tex>I_{j}</tex>.
}}
==Пример==
Построим список разбора для строки <tex>w = (a + a)</tex> в грамматике со следующими правилами:
* <tex>S \rightarrow T + S</tex>;* <tex>S \rightarrow T </tex>;* <tex>T \rightarrow F * T</tex>;* <tex>T \rightarrow F</tex>;* <tex>F \rightarrow ( S )</tex>;* <tex>F \rightarrow a</tex>.
{|
{| class="wikitable"
|-
!<tex>I_0D_0</tex>
|-
|
{| class="wikitable"
|-
!<tex>I_1D_1</tex>
|-
|
{| class="wikitable"
|-
!<tex>I_2D_2</tex>
|-
|
{| class="wikitable"
|-
!<tex>I_3D_3</tex>
|-
|
{| class="wikitable"
|-
!<tex>I_4D_4</tex>
|-
|
{| class="wikitable"
|-
!<tex>I_5D_5</tex>
|-
|
|}
Так как <tex>[S' \rightarrow S \cdot , 0] \in I_5D_5</tex>, то <tex>w \in L(G) </tex>.<br> ==См. также==* [[Алгоритм Кока-Янгера-Касами разбора грамматики в НФХ]]* [[Алгоритм Кока-Янгера-Касами, модификация для произвольной грамматики]]
==ЛитератураИсточники информации==''*[http://lpcs.math.msu.su/~sk/lehre/fivt2013/Earley.pdf Алексей Сорокин {{---}} Алгоритм Эрли]* Ахо А., Ульман Д.'' {{---}} Теория синтакcического анализа, перевода и компиляции. Том 1. Синтаксический анализ. Пер. с англ. {{---}} М.:«Мир», 1978. С. 358 — 364.
[[Категория: Теория формальных языков]]
[[Категория: Контекстно-свободные грамматики]]
[[Категория: Алгоритмы разбора]]
69
правок

Навигация