Добавить 6. Создание новых операторов и выражений с помощью библиотеки Sage++.
@@ -0,0 +1,39 @@
|
||||
В данном разделе рассмотрено изменение дерева разбора, представленное с помощью библиотеки Sage++. Добавление нового оператора или выражения состоит из следующих шагов:
|
||||
- Необходимо определить вариант (`variant()`) добавляемого оператора или выражения
|
||||
- Необходимо определить класс добавляемого оператора или выражения. Можно использовать как базовые классы (**SgStatement** / **SgExpression**), либо производные, например, **SgForStmt**.
|
||||
- Выделить память для нового выражения или оператора. Все операторы и выражения (_да и вообще все сущности Sage++_) могут использовать только по указателю.
|
||||
- Вставить полученный оператор или выражения в дерево разбора.
|
||||
- После вставки оператора в дерево его также можно наполнить выражениями в соответствии с правилами формирования конкретного оператора. С помощью функции `SgStatement::setExpression(int i, SgExpression &e)` - можно вставить соответствующее выражение в позицию i = 0, 1, 2.
|
||||
|
||||
Вставка оператора делается с помощью следующих основных функций:
|
||||
- `InsertStmtBefore `- вставить до текущего оператора, и `InsertStmtAfter `- вставить после текущего оператора. Данные функции принимают первым параметром новый оператор и вторым - оператор родитель. Второй параметр рекомендуется указывать явно для исключения ошибки в структуре полученного кода.
|
||||
|
||||
Вставка выражения делается с помощью следующих основных функций:
|
||||
- `setLsh()` - установить (добавить ссылку) в левое поддерево, и `setRsh()` - установить (_добавить ссылку_) в правое поддерево.
|
||||
|
||||
Также есть возможность вставить в дерево разбора копию оператора или выражения. Для этого необходимо использовать функции `copy()`, `copyPtr()` для того, чтобы создать соответствующую копию для вставки в дерево разбора. Необходимо следить за тем, чтобы в дереве разбора не было вставлено, например, одно выражение в нескольких местах (одна и та же ссылка в разных местах дерева). Для этих целей необходимо создавать копию.
|
||||
|
||||
Например, для того, чтобы создать следующий код на языке Фортран:
|
||||
```
|
||||
DO i_=1,N
|
||||
DO j_=1,N
|
||||
A = A + B
|
||||
ENDDO
|
||||
ENDDO
|
||||
```
|
||||
необходимо в проходе SAPFOR использовать следующий код на C++:
|
||||
|
||||
```
|
||||
SgSymbol* N_symb = ...;
|
||||
SgSymbol* i_ = findSymbolOrCreate(file, "i_" + to_string(i), SgTypeInt(), scope);
|
||||
SgSymbol* j_ = findSymbolOrCreate(file, "j_" + to_string(i), SgTypeInt(), scope);
|
||||
|
||||
SgStatement* body=new SgAssignStmt(*new SgVarRef(A), &(*new SgVarRef(A)+*new SgVarRef(B)));
|
||||
SgForStmt* newLoop = new SgForStmt (*j_, *new SgValueExp(1), *new SgVarRef(N_symb), *body);
|
||||
|
||||
newLoop = new SgForStmt (*i_, *new SgValueExp(1), *new SgVarRef(N_symb), *newLoop);
|
||||
```
|
||||
|
||||
Далее необходимо выполнить вставку оператора `newLoop ` в код перед или после необходимого оператора с помощью описанных выше функций `insertAfter/insertBefore`. Также нужно объявить новые переменные `i_, j_`, если они не были ранее объявлены. Данное действие выполняется с помощью функции `makeDeclaration(currStat, vector<SgSymbol*> { i_, j_});`, в которую первым параметром передается текущий оператор, по которому будет вычислена позиция вставки нового объявления, вторым - набор новых только что созданных символов. Если символы уже созданы и используются, то объявлять их не нужно.
|
||||
|
||||
Создание других операторов происходит примерно по таким же принципам. Существует набор производных классов, которые позволяют легко создавать новые операторы и наполнять их соответствующими выражениями.
|
||||
Reference in New Issue
Block a user