2015-08-29 10 views
0

В этом LR (0) автомат enter image description hereКак работает LR Automaton?

Есть переходы для некурящих терминалов, а также, что я не понимаю. Если входной сигнал aab. Затем вы попадете в состояние, которое равно A->a·. Если бы вы визуализировали состояние, которое было достигнуто путем ввода aab или любого другого входа, не было бы переходов между состояниями, у которых нет дуг между ними?

Я не понимаю, почему это отличается от DFA или NFA, где вы начинаете в исходном состоянии, и переходите только по дугам в Automata, пока не достигнете принимающего состояния.

+0

Я думаю, что намерения рисовальщиков по маркировке дуг состоят не в том, чтобы показать, какой вход вызывает переход, но также и из совпадающих правил (внутри ящиков), и таким образом вызвал переход. Таким образом, в первом поле используется правило '' A -> a .'', и, таким образом, он маркирует дугу вправо с помощью '' A''. – BitTickler

ответ

0

Переходы, помеченные nonterminal, выполняются только после выполнения операции уменьшения. Когда вы сделаете сокращение, вы удалите некоторое количество символов из стека разбора, а затем вставьте нетерминал в стек. В этот момент вы будете следить за переходом, отмеченным этим конкретным нетерминалом.

Автоматический синтаксический анализатор отличается от типичного DFA или NFA тем, что он предназначен для управления стеком. Переходы все соответствуют различным действиям в стеке синтаксического анализа; каждый терминал соответствует сдвигу, завершенные элементы соответствуют сокращениям, а нетерминалы говорят вам, куда идти после выполнения сокращения. Теоретически, LR-автомат является управлением для детерминированного автомата толкания, если это помогает.

+0

Я не уверен, что терминология чиста в этом ответе. LR (0) отличается от LL (0). Хотя вы можете использовать синтаксические анализаторы сдвига для анализа LR (0), основная семантика терминов LR/LL заключается в том, где рекурсии отображаются в продуктах: Пример: '' LL: B -> B | a, LR: B - > a | B''. Я не уверен, что это идеальная идея связать LR со сдвигом в синонимом виде. LR/LL классифицируют признаки грамматики и не подразумевают алгоритм. – BitTickler

+0

@BitTickler: синтаксический разбор/анализ синтаксического анализа. Разбор LL - это рекурсивный спуск, а не сдвиг/уменьшение. –

1

В парсинге LR используется стоп-кадр состояний, который в любой точке представляет собой набор не полностью признанных производств в синтаксическом анализе. Когда достигается состояние с полным производством (точка находится в конце, такая как «A -> a.»), это означает, что у стека есть символы с правой стороны этой продукции вверху. Вы выталкиваете их, чтобы вернуться в состояние, которое запустило эту конкретную последовательность переходов, и теперь переходим к не-терминалу в левой части этого производства.

Так что, если вы достигнете 'A -> a.', вам нужно создать резервную копию одного перехода (путь с пометкой «a») и вместо этого принять переход «A». Если вы достигнете «S -> AB.», вам нужно выполнить резервное копирование двух переходов и вместо этого перейти на «S». И так далее.

Нет такого возврата (или соответствующей необходимости поддержания стека) с помощью DFA или NFA.

+0

Так что сокращение действительно не включено в диаграмму автомата? Как в ней нет дуг? –

+0

Чтобы немного уточнить, когда вы следуете за стрелкой, переходящей в состояние, вы всегда нажимаете новое состояние в стеке, оставляя там старое состояние - в отличие от FA, где есть только одно текущее состояние. Государства остаются в стеке до тех пор, пока они не будут сброшены сокращением, и первое состояние в нижней части стека никогда не будет вытолкнуто. –

+0

@ Джонатан, да, это так. Сокращения составляют откат, а стрелки - только сдвиги. – arayq2

0

Автомат LR - это пусковой автомат, который использует стек состояний, а не одно текущее состояние, как с DFA. Действия (shift, reduce и goto) управляются государством, находящимся в верхней части стека, со сдвигом и goto, нажимая новое состояние и уменьшая количество фиксированных состояний на основе уменьшаемого правила. В вашем примере, если мы подсчитаем состояния в столбцах (так что 0 - начальное состояние в верхнем левом углу, 3 - состояние в среднем столбце), мы можем показать, как он анализирует входную строку «ab»:

Action    Stack 
initial state  0 
shift a    0 1 
reduce A->a   0 
goto A    0 3 
shift b    0 3 4 
reduce B->b   0 3 
goto B    0 3 5 
reduce S->AB  0 
goto S    0 2 
accept 

Поскольку это парсер LR (0), каждое состояние имеет либо действие shift/goto, либо одно действие уменьшения, и нет необходимости в поиске, чтобы знать, что делать дальше (хотя сдвиг, который потребляет входной токен, зависят от этого токена, чтобы определить, какое состояние переключиться на).

Для ввода «AAB» процесс только немного дольше:

Action    Stack 
initial state  0 
shift a    0 1 
reduce A->a   0 
goto A    0 3 
shift a    0 3 1 
reduce A->a   0 3 
goto A    0 3 3 
shift b    0 3 3 4 
reduce B->b   0 3 3 
goto B    0 3 3 5 
reduce S->AB  0 3 
goto S    0 3 6 
reduce B->S   0 3 
goto B    0 3 5 
reduce S->AB  0 
goto S    0 2 
accept 

показывает эффект правой возвратных степенных правило, чтобы соответствовать несколько элементов а на входе (B -> S -> AB), что приводит к тому, что все а сдвинуты (нажатие состояний в стеке) до тех пор, пока не будет достигнута окончательная последовательность повторной последовательности, а затем серия действий reduce/goto, чтобы отбросить их. Лучше использовать леворекурсивное правило и использует фиксированное количество пространства стека, чередуя смены и уменьшая.