Хороший дизайн AST для языка c-like (для llvm) - PullRequest
0 голосов
/ 13 сентября 2011

Я пытаюсь использовать llvm для реализации простого, тупого c-подобного языка. И я застрял в разработке хорошего АСТ.

Например, мне интересно, если разделение переменной на два вида узлов является хорошей идеей: один для распределения и один для загрузки. Я пробовал это, но я столкнулся с некоторыми препятствиями:

Foo = asd = 3; 

В этом случае Foo и add будут распределением, но add также будет загрузкой. Но узлы ast объединяются с помощью методов code ().

Есть ли хорошие ресурсы по разработке ast? (Я пытался найти кланг, но это довольно сложно понять из его исходных файлов.)

Ответы [ 2 ]

2 голосов
/ 13 сентября 2011

В большинстве языков, которые допускают такой тип ввода, для результата, который будет проанализирован как

Foo = (asd = 3);

и Foo, будет присвоен результат выражения asd = 3.Как правило, это значение asd, но AST не обязательно представляет это.

AST обычно не представляет семантику, такую ​​как «доступ на чтение» в любом случае.Это графическое представление синтаксиса , а синтаксис - это просто «назначение с левой переменной Foo и с правой стороны (назначение с левой переменной asd и целочисленной постоянной правой стороны 3) ”.

Если я правильно запомнил пример Калейдоскопа, вы увидите, что каждый оператор возвращает значение.Большинство из них будут оптимизированы дальше по цепочке, но это самый простой способ получить полезное поведение для вложенных заданий и тому подобного.Очевидно, что левая часть задания требует особого подхода, но ничего сложного для понимания или реализации трудно.

1 голос
/ 14 сентября 2011

Возможно, вы сможете черпать вдохновение из пакета Go AST: http://golang.org/pkg/go/ast/

Это C-подобный язык, хотя ваш пример неприменим, так как присваивание в Go - это утверждение и невернуть значение.Если это произойдет, ваш код проанализирует что-то вроде этого: (это псевдо-Go, но, будем надеяться, это будет понятно людям, которые этого не знают)

AssignExpr{
    Lhs: Ident{
        Name: "Foo",
    },
    Tok: token.ASSIGN
    Rhs: AssignExpr{
        Lhs: Ident{
            Name: "asd",
        },
        Rhs: BasicLit{
            Kind: token.INT,
            Value: "3",
        },
    },
}
...