LR(1) анализирует прямо в абстрактное синтаксическое дерево

Поэтому я задал вопрос закрыть это недавно и получил очень хороший ответ. Однако описанные шаги больше походили на шаги по созданию конкретного синтаксического дерева.

Каждое сокращение в процессе синтаксического анализа LR соответствует внутреннему узлу в дереве синтаксического анализа. Сокращаемое правило — это внутренний узел AST, а элементы, извлеченные из стека, соответствуют дочерним элементам этого внутреннего узла. Элемент, нажимаемый для перехода, соответствует внутреннему узлу, а элементы, нажимаемые действиями сдвига, соответствуют листьям (токенам) AST.

Собрав все это воедино, вы можете легко построить AST, создавая новый внутренний узел каждый раз, когда вы выполняете сокращение, и соединяя все вместе соответствующим образом. ~ Крис Додд

Я знаю, что дерево синтаксического анализа подразумевается предпринятыми шагами, однако я не хочу явно строить дерево синтаксического анализа. И кажется, что создание узла при каждом сокращении приведет к полному дереву синтаксического анализа. Я считал, что я создаю узел только в том случае, если наблюдается определенное состояние. Однако похоже, что это не будет работать должным образом.


person Devin Wall    schedule 26.05.2015    source источник


Ответы (1)


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

Во многих случаях AST представляет собой упрощение полного дерева синтаксического анализа, соответствующее приведенному выше.

Простой пример для грамматики выражений с использованием генератора синтаксического анализатора, подобного yacc:

expr: term            { $$ = $1; /* see below */ }
    | expr '+' term   { $$ = new_sum_node($1, $3); }
term: factor          { $$ = $1; /* see below */ }
    | term '*' factor { $$ = new_product_node($1, $3); }
factor: '(' expr ')'  { $$ = $2; /* See below */ }
      | ID            { $$ = new_variable_node($1); }
      | NUMBER        { $$ = new_literal_node($1); }

AST строится как семантическое значение нетерминалов. Ожидается, что функции new_*_node вернут вновь выделенный узел указанного типа. (Здесь мы предполагаем, что существует какой-то механизм для определения типа узла по указателю. Например, можно было бы использовать подтипы и виртуальные функции.)

В Yacc (и подобных генераторах синтаксических анализаторов) каждый символ (терминальный или нетерминальный) имеет связанное «значение», и у каждой продукции есть связанное действие, которое выполняется при сокращении продукции. Действие по производству может присваивать «стоимость» нетерминала, подлежащего сокращению. Действие может использовать «значения» компонентов правой части, поскольку каждый из них является либо терминалом (значение которого было установлено сканером), либо нетерминалом, который уже был уменьшен. По сути, это S-атрибутивная грамматика.

Некоторые из вышеперечисленных снижений вообще не проявляются в AST. В частности, единичные сокращения (expr:term и term:factor) просто проходят через AST для правой части. Точно так же сокращение скобок term:'(' expr ')' просто проходит через AST для expr, в результате чего скобки фактически исчезают из AST. (Это верно не для всех языков; в некоторых языках явно избыточные круглые скобки на самом деле влияют на семантику, и вам нужно создать узел AST, чтобы записать этот факт.)

В Yacc $$ = $1 является действием сокращения по умолчанию, если никакое действие не указано, и, поскольку большинство сокращений единиц исключаются из AST, они обычно отображаются без действий сокращения. Я сделал их явными в дидактических целях; на практике этого делать не следует.

person rici    schedule 27.05.2015
comment
Вы не возражаете, если я попрошу вас более подробно остановиться на проходе и действии по умолчанию. Также я не знаком с обозначением $$. Это просто представление переменной? Извините, если это глупый вопрос, по какой-то причине мой разум просто с трудом справляется с этой конкретной проблемой. Но спасибо за ответ! - person Devin Wall; 27.05.2015
comment
@devin: извините, я предполагал генератор синтаксических анализаторов, подобный yacc, я должен был быть более явным. В yacc установка $$ устанавливает значение сокращенного нетерминала. Значения символов в правой части: $1, $2 и т. д. - person rici; 27.05.2015
comment
@DevinWall: Надеюсь, что дополнительное объяснение несколько поможет. - person rici; 27.05.2015
comment
Хорошо, спасибо. Так и должно быть. На самом деле я пошел трудным путем, я написал свой собственный генератор таблиц LR (1) и структуру синтаксического анализатора. - person Devin Wall; 27.05.2015