Как получить АСТ от YACC? - PullRequest
       55

Как получить АСТ от YACC?

6 голосов
/ 13 апреля 2011

Я знаю, как заставить YACC генерировать AST, но как вы на самом деле получаете его? Я имею в виду, как вы на самом деле получаете значение корневого узла от YACC?

Ответы [ 4 ]

6 голосов
/ 13 апреля 2011

Yacc возвращает вам только один узел за раз, и это всегда то, что вы только что дали yacc в более раннее время, т. Е. Все, что вы хотели вернуть из сокращенного производства, или то, что вы хотеливозврат из терминального символа.(Извините, вы сказали, что знаете это, но некоторые люди, читающие это, могут не знать.)

Итак, возьмите все, что вы вернули, из корневого или верхнего правила и сохраните его (в прилагаемом коде сокращения C)как угодно.

2 голосов
/ 13 апреля 2011

Yacc дает вам дерево разбора, которое отличается от AST.Вам нужно создать свой AST самостоятельно, проходя через каждый узел дерева разбора (через yacc).

0 голосов
/ 21 августа 2013

Вот как я это сделал:

в файле yacc (your_grammar.y):

%parse-param {AstNode **pproot}
%parse-param {char **errmsg}

в вызывающей программе (your_program.c):

res = yyparse(&pAst, &errmsg);

Узлы AST размещены и связаны как дерево внутри yyparse () (вы создаете логику), а адрес корневого узла передается обратно в указатель pAst.

0 голосов
/ 20 августа 2013

Это не так элегантно, как синтаксический анализатор, возвращающий AST напрямую, но лучший способ, который я придумала для этого, - это иметь глобальную структуру данных (например, вектор или связанный список) с поточными безопасными методами вставки.если требуется безопасность потока, и правило верхнего уровня yacc добавляет свой результат (он же $$) к этой структуре данных.Затем вы можете получить доступ к этому результату в других функциях.Конечно, если вы собираетесь вывести только один AST, вероятно, необходимо иметь только один глобальный указатель на этот AST, а не структуру данных, полную их.

...