<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=217.66.159.66&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=217.66.159.66&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/217.66.159.66"/>
		<updated>2026-05-19T18:04:16Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=LR(k)-%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=49179</id>
		<title>LR(k)-грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=LR(k)-%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=49179"/>
				<updated>2015-09-03T15:37:11Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.159.66: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Восходящий разбор '''(англ. ''Bottom-up parsing)'' предназначен для построения [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора#Дерево_разбора|дерева разбора]]. Мы можем представить себе этот процесс как &amp;quot;свертку&amp;quot; исходной строки &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; к стартовому нетерминалу грамматики. Каждый шаг свертки заключается в сопоставлении некоторой подстроки &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; и правой части какого-то правила грамматики, затем происходит замена этой подстроки на нетерминал, являющийся левой частью правила. Восходящий разбор менее интуитивный, чем нисходящий, но зато позволяет разбирать большее множество грамматик.&lt;br /&gt;
&lt;br /&gt;
== LR(k)-грамматика ==&lt;br /&gt;
=== Определение ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id=def_augmented_grammar) &lt;br /&gt;
|definition=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\Gamma =\langle \Sigma, N, E, P \rangle&amp;lt;/tex&amp;gt; {{---}} [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|контекстно-свободная]] грамматика. '''Пополненной грамматикой''' (англ. ''augmented grammar''), полученной из &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, назовем грамматику &amp;lt;tex&amp;gt;\Gamma' =\langle \Sigma', N', E_0, P' \rangle&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\Sigma' = \Sigma; N' = N \cup \{E_0\}; E_0 \notin N; P' = P \cup \{E_0 \to E\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|id=def_LR_K &lt;br /&gt;
|definition=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\Gamma' =\langle \Sigma', N', E_0, P' \rangle&amp;lt;/tex&amp;gt; {{---}} пополненная грамматика для КС-грамматики &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;. Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; является '''LR(k)-грамматикой''', если из того, что для любых двух [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора#Лево-_и_правосторонний_вывод_слова|правосторонних выводов]] верно, что:&lt;br /&gt;
* &amp;lt;tex&amp;gt;E_0 \Rightarrow^* \beta A t z \Rightarrow \beta \alpha t z  \Rightarrow^* w,   &amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;|t|=k&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;|t|&amp;lt;k, |z|=0 (z = \varepsilon)&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt;E_0 \Rightarrow^* \gamma B t z' \Rightarrow \gamma \xi t z' \Rightarrow^* w',  &amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;|t|=k&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;|t|&amp;lt;k, |z'|=0 (z' = \varepsilon)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
следует, что &amp;lt;tex&amp;gt;\beta \alpha = \gamma \xi&amp;lt;/tex&amp;gt;, &lt;br /&gt;
&lt;br /&gt;
тогда &amp;lt;tex&amp;gt;\beta = \gamma&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A = B&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Говоря неформально, мы делаем правостороннюю свёртку нашей строки в стартовый нетерминал. Если по не более чем &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; символам неразобранной части строки мы можем однозначно определить, во что сворачивается хвост выведенного правила, то грамматика будет LR(k).&lt;br /&gt;
&lt;br /&gt;
LR(k) означает, что &lt;br /&gt;
* входная цепочка обрабатывается слева направо (англ. ''left-to-right parse''),&lt;br /&gt;
* выполняется правый вывод (англ. ''rightmost derivation''),&lt;br /&gt;
* не более &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; символов цепочки (англ. ''k-token lookahead'') используются для принятия решения.&lt;br /&gt;
&lt;br /&gt;
===Замечание о пополненной грамматике===&lt;br /&gt;
&lt;br /&gt;
Использование в определении LR(k)-грамматики пополненной грамматики существенно для однозначного определения конца анализа. Действительно, если грамматика использует &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; в правых частях правил, то свертка основы в &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; не может служить сигналом приема входной цепочки. Свертка же в &amp;lt;tex&amp;gt;E_0&amp;lt;/tex&amp;gt; в пополненной грамматике служит таким сигналом, поскольку &amp;lt;tex&amp;gt;E_0&amp;lt;/tex&amp;gt; нигде, кроме начальной сентенциальной формы, не встречается.&lt;br /&gt;
&lt;br /&gt;
Существенность использования пополненной грамматики в определении LR(k)-грамматик продемонстрируем на следующем конкретном примере. Пусть пополненная грамматика имеет следующие правила: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
(0)\ E_0 \to E \\&lt;br /&gt;
(1)\ E \to Ea \\&lt;br /&gt;
(2)\ E \to a \\&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если игнорировать &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;-е правило, то, не заглядывая в правый контекст основы &amp;lt;tex&amp;gt;Ea&amp;lt;/tex&amp;gt;, можно сказать, что она должна сворачиваться в &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt;. Аналогично основа &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; безусловно должна сворачиваться в &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt;. Создается впечатление, что данная грамматика без &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;-го правила есть LR(0)-грамматика. Но на самом деле это не так, в этом можно убедиться рассмотрев процесс [[LR(0)-разбор|LR(0)-разбора]].&lt;br /&gt;
&lt;br /&gt;
== LR-разборщик ==&lt;br /&gt;
&lt;br /&gt;
=== Принцип переноса-свёртки ===&lt;br /&gt;
При LR(k)-анализе применяется метод '''перенос-свертка''' (англ. ''shift-reduce''). Суть метода сводится к следующему:&lt;br /&gt;
# Программа анализатора читает последовательно символы входной строки до тех пор, пока не накопится цепочка, совпадающая с правой частью какого-нибудь из правил. Рассмотренные символы переносим в стек (операция '''перенос'''). &lt;br /&gt;
# Далее все символы совпадающей цепочки извлекаются из стека и на их место помещается нетерминал, находящийся в левой части этого правила (операция '''свертка''').&lt;br /&gt;
&lt;br /&gt;
=== Структура ===&lt;br /&gt;
Метод '''перенос-свертка''' использует следующие компоненты:&lt;br /&gt;
* входная строка, &lt;br /&gt;
* стек (для запоминания рассмотренных символов),&lt;br /&gt;
* управляющая таблица (для определения, какое действие применить {{---}} перенос или свертку),&lt;br /&gt;
* автомат (для запоминания информации о текущем состоянии стека).&lt;br /&gt;
&lt;br /&gt;
=== Управляющая программа анализатора ===&lt;br /&gt;
Управляющая программа одинакова для всех LR-анализаторов, а таблица и автомат изменяются от одного анализатора к другому. &lt;br /&gt;
&lt;br /&gt;
Для запоминания строки запись в [[Стек|стек]] имеет вид: &amp;lt;tex&amp;gt;s_0X_1s_1X_2...X_ms_m&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;s_m&amp;lt;/tex&amp;gt; {{---}} вершина стека. Каждый &amp;lt;tex&amp;gt;X_i&amp;lt;/tex&amp;gt; {{---}} символ грамматики (терминал или нетерминал), а &amp;lt;tex&amp;gt;s_i&amp;lt;/tex&amp;gt; {{---}} состояние автомата. Каждое состояние суммирует информацию, cодержащуюся в стеке перед ним. &amp;lt;tex&amp;gt;s_0&amp;lt;/tex&amp;gt; {{---}} стартовое состояние автомата.&lt;br /&gt;
Комбинация символа состояния на вершине стека и текущего входного символа используется для индексирования управляющей таблицы и определения операции переноса-свертки. При реализации грамматические символы не обязательно располагаются в стеке, однако, мы будем использовать их при обсуждении для лучшего понимания поведения LR-анализатора. &lt;br /&gt;
&lt;br /&gt;
Обращение к таблице происходит следующим образом &amp;lt;tex&amp;gt;\mathtt{T[state, token]}&amp;lt;/tex&amp;gt;, где &lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathtt{state}&amp;lt;/tex&amp;gt; {{---}} состояние автомата, &lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathtt{token}&amp;lt;/tex&amp;gt; {{---}} входной символ. &lt;br /&gt;
Полученное значение в таблице должно информировать о текущем действии, то есть о переносе или свертке. В этих двух случаях, необходима дополнительная информация: к какому состоянию происходит переход (при переносе) и по какому правилу происходит свертка. В случае некорректного входного символа происходит ошибка, а свертка в стартовое состояние идентифицируется как допуск:&lt;br /&gt;
 '''struct''' Cell&lt;br /&gt;
    enum: &lt;br /&gt;
        Shift &lt;br /&gt;
        Reduce &lt;br /&gt;
        Error    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// ошибка&amp;lt;/font&amp;gt;&lt;br /&gt;
        Accept   &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// допуск &amp;lt;/font&amp;gt;&lt;br /&gt;
 '''struct''' Shift &lt;br /&gt;
     state: '''int'''  &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// переход в стостояние state&amp;lt;/font&amp;gt;&lt;br /&gt;
 '''struct''' Reduce &lt;br /&gt;
     rule: '''int'''   &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// свертка по правилу rule&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Рузультатом работы управляющей программы будет:&lt;br /&gt;
 '''struct''' Result&lt;br /&gt;
    enum:  &lt;br /&gt;
        Accept   &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// допуск &amp;lt;/font&amp;gt;&lt;br /&gt;
        Error    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// ошибка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Алгоритм ===&lt;br /&gt;
# Программа читает символ из входной цепочки. &lt;br /&gt;
# Обращается к управляющей таблице.&lt;br /&gt;
# Совершает соответствующее действие.&lt;br /&gt;
# Возвращается к первому пункту, пока входная цепочка не закончится.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; &lt;br /&gt;
|align=&amp;quot;left&amp;quot; colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
&amp;lt;font size=2&amp;gt;&lt;br /&gt;
  '''Result''' algorithmLR(w: '''string''')&lt;br /&gt;
      curToken {{---}} указатель на первый символ в строке w&lt;br /&gt;
      '''while''' haveToken()&lt;br /&gt;
          curState = top()&lt;br /&gt;
          '''if''' &amp;lt;tex&amp;gt;\mathtt{T}&amp;lt;/tex&amp;gt;[curState, curToken] == Shift s &lt;br /&gt;
              push(curToken)&lt;br /&gt;
              push(s)&lt;br /&gt;
              nextToken()&lt;br /&gt;
          '''else if''' &amp;lt;tex&amp;gt;\mathtt{T}&amp;lt;/tex&amp;gt;[curState, curToken] == Reduce &amp;lt;tex&amp;gt; A  \to \beta&amp;lt;/tex&amp;gt; &lt;br /&gt;
              '''for''' j = 1 '''to''' &amp;lt;tex&amp;gt;|\beta |&amp;lt;/tex&amp;gt;  &lt;br /&gt;
                  pop()&lt;br /&gt;
                  pop()&lt;br /&gt;
              s = top()&lt;br /&gt;
              push(&amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;)&lt;br /&gt;
              push(goto [s, &amp;lt;tex&amp;gt;A]&amp;lt;/tex&amp;gt;) &lt;br /&gt;
              Вывод правила (&amp;lt;tex&amp;gt; A \to \beta&amp;lt;/tex&amp;gt;)&lt;br /&gt;
          '''else''' '''if''' &amp;lt;tex&amp;gt;\mathtt{T}&amp;lt;/tex&amp;gt;[curState, curToken] == Accept &lt;br /&gt;
              '''return''' Accept&lt;br /&gt;
          '''else''' &lt;br /&gt;
              '''return''' Error     &lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;tex&amp;gt;goto&amp;lt;/tex&amp;gt; получает состояние и символ грамматики и выдает состояние. Функция &amp;lt;tex&amp;gt;goto&amp;lt;/tex&amp;gt;, строящаяся по грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, есть функция переходов детерминированного магазинного автомата, который распознает язык,&lt;br /&gt;
порождаемый грамматикой &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Предиктивный синтаксический анализ]]&lt;br /&gt;
* [[LL(k)-грамматики, множества FIRST и FOLLOW]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Альфред Ахо, Рави Сети, Джеффри Ульман. Компиляторы. Принципы, технологии, инструменты. Издательство Вильямс, 2003. Стр. 301-326.&lt;br /&gt;
* [http://ict.edu.ru/ft/005128//ch7.pdf Терехов Ан.А., Вояковская Н., Булычев Д., Москаль А. Разработка компиляторов на платформе .NET {{---}} Восходящие анализаторы]&lt;br /&gt;
* [http://window.edu.ru/resource/974/69974/files/lang_trans.pdf Б.К.Мартыненко. Языки и трансляции. Стр. 198-223]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Методы трансляции]]&lt;br /&gt;
[[Категория: Восходящий разбор]]&lt;/div&gt;</summary>
		<author><name>217.66.159.66</name></author>	</entry>

	</feed>