分享
 
 
 

little c解释器分析[二]

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

/* ------------------------------------------------------------------------------------- */

/* 递归下降分析算法:little c解释器是采用递归下降来进行表达式分析的 */

/* ------------------------------------------------------------------------------------- */

exp_x递归的描述

--------------------

因为涉及到优先级的问题,所以从exp_1开始的递归子程序,都是越后递归所要完成的任务的优先级越高

,exp_1开始执行后,并不完成其本身的任务,而是向下递归,只到最下面一个子程序,然后返回,在返回的

过程中根据优先级来先后完成当前的任务。

首先从exp_0开始,其检查是否是空表达式,以及处理变量。在处理变量过程中又递归运行,使变量赋值。

exp_1主要完成的任务是计算布尔表达式,其计算过程中需要在次递归调用得到第2个值好和第一个值进行布尔

计算。

exp_2主要完成的任务是计算处理加法和减法运算。其运算过程中需要查看其后的运算时候是乘法或除法,

如果是需要先进行计算,所以在while内部需要调用exp_3,如果是4+28*2这样的,那么当exp_3返回时就会返回

56,然后才进行加法运算。此程序还需要处理7+1+2+1这样的连加或连减.

exp_3主要完成的任务是计算除法和取摸。其功能类似加减。

exp_4处理一元加或减。

exp_5最高优先级别,是()运算,

atom负责内部函数和用户定义的函数调用,并返回值给全局变量value,和返回常量值以及数字值。

----------------------

/* Entry point into parser. */

/* 分析部分程序开始执行 */

/* 程序的入口是eval_exp()函数 */

void eval_exp(int *value)

{

/* 首先取得一个符号 */

get_token();

/* 判断是否有符号,如果没有返回错误,没有表达式 */

if(!*token) {

sntx_err(NO_EXP);

return;

}

/* 如果“单词”为 ";" 的话,那么表示是一个空表达式,空表达式的值为0,表示假 */

if(*token == ';') {

*value = 0; /* empty expression */

return;

}

/* 如果不是上面2种情况,那么表达式递归分析开始执行 */

eval_exp0(value);

putback(); /* return last token read to input stream */

}

/* Process an assignment expression */

void eval_exp0(int *value)

{

char temp[ID_LEN]; /* holds name of var receiving

the assignment */

register int temp_tok;

if(token_type == IDENTIFIER) {

/* 通过变量is_var查看这个“标示符”是否已经在全局或局部变量表中 */

if(is_var(token)) { /* if a var, see if assignment */

/* 如果在的话,那么把token复制到temp变量中 */

strcpy(temp, token);

//如果不在话那么将先把token内存放的值copy到temp里,因为确定是赋值语句,那么就可能是表达式,由于token是全局变量,所以要在这里保

存。

temp_tok = token_type;//缓冲标记类型设置为token_type

get_token();//取得下一个符号,根据这个变量名字还没定义,那就说明他应该是有个赋值的语句

if(*token == '=') { /* is an assignment */ //如果是一个=符号的话,那就说明他是赋值语句

get_token();//取得符号

eval_exp0(value); //递归计算表达式

assign_var(temp, *value); //给变量赋值

return;

}

else { //

putback(); //否则恢复token以前指针的位置

strcpy(token, temp); //把temp的值给token

token_type = temp_tok;//类型为temp_tok类型

}

}

}

eval_exp1(value);//递归进入下一层

}

/* Process relational operators. */

void eval_exp1(int *value)

{

int partial_value;//另一个需要计算的表达式中的值

register char op; //此变量是操作符变量

char relops[7] = {//操作符表

LT, LE, GT, GE, EQ, NE, 0

};

eval_exp2(value);//进入下一层

op = *token; //操作符

if(strchr(relops, op)) {//如果属于操作符

get_token();//取得下一个符号

eval_exp2(&partial_value);//取得partial_value的值

switch(op) { /* perform the relational operation */

case LT://处理LT的情况 小于号

*value = *value < partial_value;//处理的真假值放到values里,values此时只可能是1或0

break;//推出switch语句

case LE://处理LE的情况 小于等于号

*value = *value <= partial_value;

break;

case GT://处理GT的情况 大于号

*value = *value > partial_value;

break;

case GE://处理GE的情况 大于等于号

*value = *value >= partial_value;

break;

case EQ://处理EQ符号 测试是否相等符号

*value = *value == partial_value;

break;

case NE://处理NE符号 测试不等符号

*value = *value != partial_value;

break;

}

}

}

/* Add or subtract two terms. */

void eval_exp2(int *value)

{

register char op;

int partial_value;

eval_exp3(value);//进入递归

while((op = *token) == '+' || op == '-') {//处理多个加号或减号

get_token();//取得一个符号

eval_exp3(&partial_value);//得到一个数字。这个值可能是来自乘法或除法或表达式传回来的值

switch(op) { //选择一个符号

case '-'://处理减号

*value = *value - partial_value;

break;

case '+'://处理加号

*value = *value + partial_value;

break;

}

}

}

/* Multiply or divide two factors. */

void eval_exp3(int *value)

{

register char op;

int partial_value, t;

eval_exp4(value);//进入下一层递归

while((op = *token) == '*' || op == '/' || op == '%') {//处理连乘或连除

get_token();//取得下一个符号

eval_exp4(&partial_value);//得到一个数字

switch(op) { /* mul, div, or modulus */

case '*'://处理乘法

*value = *value * partial_value;

break;

case '/'://处理除法

if(partial_value == 0) sntx_err(DIV_BY_ZERO);

*value = (*value) / partial_value;

break;

case '%'://处理取摸运算.余数放在value里

t = (*value) / partial_value;

*value = *value-(t * partial_value);

break;

}

}

}

//eval_exp4处理一元加或减

/* Is a unary + or -. */

void eval_exp4(int *value)

{

register char op;

op = '\0';

if(*token == '+' || *token == '-') {

op = *token;

get_token();

}

eval_exp5(value);

if(op)

if(op == '-') *value = -(*value);

}

/* Process parenthesized expression. */

void eval_exp5(int *value)

{

if((*token == '(')) {//处理(,()具有最高优先级

get_token();

eval_exp0(value); /* get subexpression */

if(*token != ')') sntx_err(PAREN_EXPECTED);//如果没有)说明语法错误

get_token();

}

else

atom(value);//取得一个值

}

void atom(int *value)

{

int i;

switch(token_type) {

/* 选择token类型 */

case IDENTIFIER:

/* 如果是变量或函数 */

i = internal_func(token);

/* 从内部结构中查找函数名是否存在 */

if(i!= -1) { /* call "standard library" function */

/* 如果不是-1的话,那么表示是内部函数 */

*value = (*intern_func.p)();

/* 通过结构中的函数指针调用内部函数,返回的值放到 value指向地址里 */

}

else if(find_func(token)) { /* call user-defined function */

/* 否则通过函数find_func查找是否是用户定义的函数,如果是的话 */

call();

/* 通过call函数调用用户定义的函数 */

*value = ret_value;

/* 函数的返回值放到value指向的地址里 */

}

else *value = find_var(token); /* get var's value */

/* 否则就认为他是一个变量的名字,通过find_var函数找到token里存放到变量值,然后放到value里 */

get_token();

/* 返回 */

return;

case NUMBER: /* is numeric constant */

/* 如果是一个数字的话 那么通过标准库函数中的atoi(在stdio.h中定义了此函数) 把字符转化为数字类型,以方便表达式计算 */

*value = atoi(token);

get_token();

/* 返回 */

return;

case DELIMITER: /* see if character constant */

/* 如果是一个字符常量的话 */

if(*token == '\'') {

/* 如果是'字符,那么把当前的值放到value里 */

*value = *prog;

prog++;

if(*prog!='\'') sntx_err(QUOTE_EXPECTED);

/* 如果不是以'符号结尾,就抛出语法错误 */

prog++;

get_token();

return ;

}

if(*token==')') return; /* process empty expression */

else sntx_err(SYNTAX); /* syntax error */

default:

sntx_err(SYNTAX); /* syntax error */

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有