Работаю над реализацией языка программирования на C++, подхожу к стадии генерации AST.
Я хотел бы использовать трехэтапную процедуру:
- Распознать тип утверждения;
- Отделите токены от выражения в lvalues rvalues и узлах как временные и локальные AST;
- Разработайте и добавьте его в глобальный AST.
Вот что это даст, например, для объявления переменной:
var MyVar : integer = 8 + 2;
Временная форма (rvalues/node/lvalues):
left:
-left:
"MyVar"
-node:
":"
-right:
"integer"
node:
"="
right:
-left:
"8"
-node:
"+"
-right:
"2"
Представлен в виде классического AST:
"="
/ \
/ \
/ \
":" "+"
/ \ / \
/ \ "8" "2"
/ \
"MyVar" "integer"
Затем временное дерево добавляется к глобальному дереву с указанием типа объявления:
[EXP]
|
VarDecl
|
{ ... }
Это работает для всего, кроме объявлений функций и вызовов функций:
func add(a : integer, b : integer) : integer;
add(8, 2);
Действительно, для этого типа выражений нет узлов, чтобы отличить lvalue от rvalue. Я также понятия не имею, как представить параметры функции. Я думал о чем-то вроде этого:
left:
"add"
params:
[
-left:
"a"
-node:
":"
-right:
"integer"
]
[
-left:
"b"
-node:
":"
-right:
"integer"
]
node:
":"
right:
"integer"
То же самое для вызова:
left:
"add"
params:
[
"8"
]
[
"2"
]
Но я чувствую, что логики не останется, если я это сделаю.
Итак, мне было интересно, нет ли способа сделать то, что было близко к моему, чтобы улучшить его, или если мое нужно было полностью пересмотреть.
PS: я новичок в области абстрактного синтаксического анализа и деревьев, но я прочитал много документов и руководств по этой теме.