# 一个小问题

case SyntaxProductionInit.VarDecl_Equal_Initializer_TO_Decl:
attributeForParentNode = (Symbol) valueStack.get(valueStack.size() - 3);
((Symbol) attributeForParentNode).value = initialValue;
break;

case SyntaxProductionInit.Expr_TO_Initializer:
initialValue = (Integer) valueStack.get(valueStack.size() - 1);
System.out.println(initialValue);
break;


# 示例

void swap(int arr[10], int i, int j) {
int temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}

void quickSort(int a[10], int p, int r) {
int x;
int i;
i = p - 1;
int j;
int t;
int v;
v = r - 1;
if (p < r) {
x = a[r];
for (j = p; j <= v; j++) {
if (a[j] <= x) {
i++;
swap(a, i, j);
}
}
v = i + 1;
swap(a, v, r);
t = v - 1;
quickSort(a, p, t);
t = v + 1;
quickSort(a, t, r);
}
}

void main () {
int a[10];
int i;
int t;

printf("Array before quicksort:");
for(i = 0; i < 10; i++) {
t = (10 - i);
a[i] = t;
printf("value of a[%d] is %d", i, a[i]);
}

quickSort(a, 0, 9);

printf("Array after quicksort:");
for (i = 0; i < 10; i++) {
printf("value of a[%d] is %d", i, a[i]);
}
}


# Executor接口

Interpreter类的execute传入的参数就是整棵抽象语法树的头节点了，ExecutorFactory的getExecutor则是根据当前结点的TokenType返回一个可以解释当前节点的类，而其它执行节点的类都继承了BaseExecutor

@Override
public Object execute(AstNode root) {
if (root == null) {
return null;
}

ExecutorFactory factory = ExecutorFactory.getInstance();
Executor executor = factory.getExecutor(root);
executor.execute(root);

return root;
}


BaseExecutor的两个主要方法就是执行它的子节点，并且可以指定执行哪个子节点。可以先忽略Brocaster，这些是用来实现执行节点类之前的通讯的，现在还没有用。reverseChildren是用来对节点的反转，因为在创建的AST的过程由于堆栈的原因，所以节点顺序的相反的。continueExecute是标志位，后面可能会执行到设置它的节点来结束运行

protected void executeChildren(AstNode root) {
ExecutorFactory factory = ExecutorFactory.getInstance();
root.reverseChildren();

int i = 0;
while (i < root.getChildren().size()) {
if (!continueExecute) {
break;
}

AstNode child = root.getChildren().get(i);
executorBrocaster.brocastBeforeExecution(child);
Executor executor = factory.getExecutor(child);
if (executor != null) {
executor.execute(child);
} else {
System.err.println("Not suitable Generate found, node is: " + child.toString());
}

executorBrocaster.brocastAfterExecution(child);

i++;
}
}

protected AstNode executeChild(AstNode root, int childIdx) {
root.reverseChildren();
AstNode child;
ExecutorFactory factory = ExecutorFactory.getInstance();
child = (AstNode)root.getChildren().get(childIdx);
Executor executor = factory.getExecutor(child);
AstNode res = (AstNode)executor.execute(child);

return res;
}


# 解释执行

public AstNode getSyntaxTreeRoot() {
AstNode mainNode = funcMap.get("main");
return mainNode;
}


## 执行函数ExtDefExecutor

• 在进入execute会先执行FunctDecl节点，再执行CompoundStmt节点
• saveArgs和restoreArgs属于保护当前的环境，就是进入其它作用域的时候保证这个符号不变修改，不比如当作参数传递的时候
• returnVal也是属于由其它节点设置的属性
• root.setAttribute的作用就是对节点设置属性，把值往上传递
@Override
public Object execute(AstNode root) {
this.root = root;
int production = (Integer) root.getAttribute(NodeKey.PRODUCTION);
switch (production) {
case SyntaxProductionInit.OptSpecifiers_FunctDecl_CompoundStmt_TO_ExtDef:
AstNode child = root.getChildren().get(0);
funcName = (String) child.getAttribute(NodeKey.TEXT);
root.setAttribute(NodeKey.TEXT, funcName);
saveArgs();
executeChild(root, 0);

executeChild(root, 1);
Object returnVal = getReturnObj();
clearReturnObj();

if (returnVal != null) {
root.setAttribute(NodeKey.VALUE, returnVal);
}
isContinueExecution(true);
restoreArgs();
break;

default:
break;
}
return root;
}


### 函数定义 FunctDeclExecutor

@Override
public Object execute(AstNode root) {
int production = (Integer) root.getAttribute(NodeKey.PRODUCTION);
Symbol symbol;
currentNode = root;

switch (production) {
case SyntaxProductionInit.NewName_LP_RP_TO_FunctDecl:
root.reverseChildren();
copyChild(root, root.getChildren().get(0));
break;

case SyntaxProductionInit.NewName_LP_VarList_RP_TO_FunctDecl:
symbol = (Symbol) root.getAttribute(NodeKey.SYMBOL);

Symbol args = symbol.getArgList();
initArgumentList(args);

if (args == null || argsList == null || argsList.isEmpty()) {
System.err.println("generate function with arg list but arg list is null");
System.exit(1);
}
break;

default:
break;
}

return root;
}


### 执行语句部分 CompoundStmtExecutor

COMPOUND_STMT-> LC LOCAL_DEFS STMT_LIST RC


@Override
public Object execute(AstNode root) {
return executeChild(root, 0);
}


# 一元操作

• ### 指针

ValueSetter是一个可以对变量进行赋值的接口，数组、指针、简单的变量都有各自的valueSetter

case SyntaxProductionInit.Start_Unary_TO_Unary:
child = root.getChildren().get(0);
symbol = (Symbol) child.getAttribute(NodeKey.SYMBOL);

MemoryHeap memHeap = MemoryHeap.getInstance();
int offset = addr - entry.getKey();
if (entry != null) {
byte[] memByte = entry.getValue();
root.setAttribute(NodeKey.VALUE, memByte[offset]);
}

root.setAttribute(NodeKey.SYMBOL, directMemSetter);
break;

• ### 指针和数组操作：

case SyntaxProductionInit.Unary_LB_Expr_RB_TO_Unary:
child = root.getChildren().get(0);
symbol = (Symbol) child.getAttribute(NodeKey.SYMBOL);

child = root.getChildren().get(1);
int index = (Integer) child.getAttribute(NodeKey.VALUE);

try {
Declarator declarator = symbol.getDeclarator(Declarator.ARRAY);
if (declarator != null) {
Object val = declarator.getElement(index);
root.setAttribute(NodeKey.VALUE, val);
ArrayValueSetter setter = new ArrayValueSetter(symbol, index);
root.setAttribute(NodeKey.SYMBOL, setter);
root.setAttribute(NodeKey.TEXT, symbol.getName());
}
Declarator pointer = symbol.getDeclarator(Declarator.POINTER);
if (pointer != null) {
setPointerValue(root, symbol, index);

PointerValueSetter pv = new PointerValueSetter(symbol, index);
root.setAttribute(NodeKey.SYMBOL, pv);
root.setAttribute(NodeKey.TEXT, symbol.getName());
}

} catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace();
System.exit(1);
}
break;

• ### 函数调用

1. 如果是自定义函数，就找到这个函数的头节点，从这个头节点开始执行
2. 如果是解释器提供的函数，就交由ClibCall处理，比如printf就是属于库函数
case SyntaxProductionInit.Unary_LP_RP_TO_Unary:
case SyntaxProductionInit.Unary_LP_ARGS_RP_TO_Unary:
String funcName = (String) root.getChildren().get(0).getAttribute(NodeKey.TEXT);
if (production == SyntaxProductionInit.Unary_LP_ARGS_RP_TO_Unary) {
AstNode argsNode = root.getChildren().get(1);
ArrayList<Object> argList = (ArrayList<Object>) argsNode.getAttribute(NodeKey.VALUE);
ArrayList<Object> symList = (ArrayList<Object>) argsNode.getAttribute(NodeKey.SYMBOL);
FunctionArgumentList.getInstance().setFuncArgList(argList);
FunctionArgumentList.getInstance().setFuncArgSymbolList(symList);
}

AstNode func = AstBuilder.getInstance().getFunctionNodeByName(funcName);
if (func != null) {
Executor executor = ExecutorFactory.getInstance().getExecutor(func);
executor.execute(func);
Object returnVal = func.getAttribute(NodeKey.VALUE);
if (returnVal != null) {
ConsoleDebugColor.outlnPurple("function call with name " + funcName + " has return value that is " + returnVal.toString());
root.setAttribute(NodeKey.VALUE, returnVal);
}
} else {
ClibCall libCall = ClibCall.getInstance();
if (libCall.isApiCall(funcName)) {
Object obj = libCall.invokeApi(funcName);
root.setAttribute(NodeKey.VALUE, obj);
}
}
break;


# 逻辑语句处理

• ### FOR、WHILE语句

for(i = 0; i < 5; i++){}


case SyntaxProductionInit.FOR_OptExpr_Test_EndOptExpr_Statement_TO_Statement:
executeChild(root, 0);

while (isLoopContinute(root, LoopType.FOR)) {
//execute statement in for body
executeChild(root, 3);
//execute EndOptExpr
executeChild(root, 2);
}
break;

case SyntaxProductionInit.While_LP_Test_Rp_TO_Statement:
while (isLoopContinute(root, LoopType.WHILE)) {
executeChild(root, 1);
}
break;

• ### IF语句

if语句就是先执行判断部分，再根据判断的结果来决定是否执行{}块

@Override
public Object execute(AstNode root) {

AstNode res = executeChild(root, 0);
Integer val = (Integer)res.getAttribute(NodeKey.VALUE);
copyChild(root, res);

if (val != null && val != 0) {
executeChild(root, 1);
}

return root;
}


# 小结

posted @ 2019-08-20 11:40  dejavudwh  阅读(305)  评论(1编辑  收藏