Изменения

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

Предиктивный синтаксический анализ

381 байт добавлено, 14:03, 25 мая 2015
Пример
E' \to +TE' \mid \varepsilon \\
T \to FT' \\
T' \to \times * FT' \mid \varepsilon \\
F \to n \mid (E)
</tex>
|-
|style="background-color:#FFF;padding:2px 30px"| <tex>T'</tex>
|style="background-color:#FFF;padding:2px 30px"| <tex>\{\ \times*,\ \varepsilon\ \} </tex>
|style="background-color:#FFF;padding:2px 30px"| <tex>\{\ +,\ \$\ ,\ )\ \}</tex>
|-
|style="background-color:#FFF;padding:2px 30px"| <tex>F</tex>
|style="background-color:#FFF;padding:2px 30px"| <tex>\{\ n,\ (\ \} </tex>
|style="background-color:#FFF;padding:2px 30px"| <tex>\{\ \times*, \ +,\ \$\ ,\ )\ \} </tex>
|}
Node res = Node("E")
'''switch''' (curToken)
'''case''' <tex> n,\ '( </tex> ' :
res.addChild(T())
res.addChild(E'())
'''break'''
'''default''' :
<font color="red">error</font>("unexpected char")
'''return''' res
E'(): '''Node''' Node res = Node("E'") '''switch''' (curToken) '''case ''' '+' :
consume('+')
res.addChild(Node("+"))
res.addChild(T())
res.addChild(E'())
'''break''' '''case ''' '$', ')' : '''break''' '''default ''' : <font color="red">error</font>("unexpected char") '''return ''' res
F(): '''Node''' Node res = Node("F") '''switch''' (curToken) '''case '''n' : consume('n') res.addChild(Node(curToken)) <font color="green">// <tex>\mathtt{curToken}</tex> подпадает под шаблон <tex>n"))</tex>, поэтому запишем его в <tex>\mathtt{value}</tex> вершины</font> '''break''' '''case ''' '(' :
consume('(')
res.addChild(Node("("))
consume(')')
res.addChild(Node(")"))
'''default ''' : <font color="red">error</font>("unexpected char") '''return ''' res
Функции для <tex>T</tex> и <tex>T'</tex> строятся аналогично.
=== Дерево разбора ===
Рассмотрим дерево разбора для выражения <tex>(1 + 2) * 3 </tex> и несколько первых шагов алгоритма рекурсивного разбора. Сначала вызывается функция стартового нетерминала грамматики, то есть <tex>E</tex>. Так как первым токеном является '(', то будет использовано первое правило разбора <tex>TE'</tex>. Поэтому к вершине с меткой <tex>E</tex> добавятся два ребёнка: <tex>T</tex> и <tex>E'</tex>. А рекурсивный разборщик перейдёт к нетерминалу <tex>T</tex>. По-прежнему curToken равен '(', поэтому в <tex>F</tex> сработает второй case, первым ребёнком добавится '(', curToken станет равен <tex>1</tex>, а разборщик перейдёт к нетерминалу <tex>E</tex>. После того как выражение после '(', которое выводится из <tex>E</tex>, будет полностью разобрано, функция рекурсивного разбора для <tex>F</tex> добавит ')' последним сыном к этому нетерминалу.
Продолжая в том же духе, мы построим всё дерево разбора данного выражения.
[[Файл:parse_ex1.png|400px|thumb|center|Дерево разбора выражения <tex>(1 + 2) * 3</tex>]]
== Нерекурсивный нисходящий парсер ==
Анонимный участник

Навигация