标签:
继上节8说到利用手动构建的语法树解析下面的c语言代码:
a = 1
sum = 0
input(x)
while(a <= x){
sum = sum + a
a = a+1;
}
print(sum)
而一个编译器不应该依赖用户去手动构建对应语言的语法树,我们需要的是一种支持自动构建语法树的策略。本节将要说明的就是如何利用前面1-6节学到的lex,yacc以及符号表,7-8节学到的语法树来支持给定c语言代码自动构建过程。
在第5节变量支持的计算器中,对于expr的语法解析有如下的yacc代码:
lines : lines expr EOL { printf("%g\n", $2); }
| lines EOL
| lines COMMENT
|
;
expr : expr PLUS expr { $$ = $1 + $3; }
| expr MINUS expr { $$ = $1 - $3; }
| expr TIMES expr { $$ = $1 * $3; }
| expr OVER expr { $$ = $1 / $3; }
| LP expr RP { $$ = $2; }
| ‘-‘ expr %prec UMINUS { $$ = -$2; }
| NUMBER {$$=$1;} //$$=$1 can be ignored
| ID {$$ = sym_table.getValue($1);}//get value from sym_table
| ID ASSIGN expr {sym_table.setValue($1, $3); $$=$3; }//modify the value
已经知道的是上面每一行都是对应的语法匹配规则(例如expr PLUS expr)以及当规则匹配后要执行的动作(位于{}中,例如$$ = $1 + $3;)。如果将上面要执行的动作修改为创建对应的语法表达式节点,不就可以实现自动构建语法树了吗? 针对上面的expr PLUS expr,其对应的动作可以修改为
$$ = expr.NewRoot(EXPR_NODE, OP_EXPR, NodeAttr(PLUS), Integer, $1, $3);
同理,其他语法规则的执行动作也可以进行相应的修改,这样当一个表达式语法分析完毕后,对应的表达式语法树也就构建完成了。
可支持如下的代码:
其为迭代法解一元二次方程组,方程的三个参数为a,b,c。
void interation()
{
//求解X1,在曲线对称轴处选择初始点
double index=(-1.0*b)/(2*a),temp;
if(b!=0)//b不等于0时进行迭代
{
temp=index;
index=-1.0*(a*temp*temp+c)/b;
while((absolute(index-temp))>accuracy)
{
temp=index;
index=-1.0*(a*temp*temp+c)/b;
}
x1=index;
x2=(-1.0*b)/a-x1;
}
else//b=0时ax^2+c=0直接求解
{
x1=sqrt(-1.0*c/a);
x2=-x1;
}
}
标签:
原文地址:http://blog.csdn.net/lpstudy/article/details/51340644