//分析 expr ast_tree *parser_expr(token_result *result) { ast_tree *tree; token *t; if((t = next_token(result)) == NULL) return NULL; if(t->type == TOKEN_NUM){ tree = new_tree(); ast_tag(tree,"expr"); return parser_num(tree, t->num); } if(t->type == TOKEN_SYM){ if(strcmp(t->sym, "(") == 0){ putback_token(); return parser_sexpr(result); } if(strcmp(t->sym, "'") == 0){ putback_token(); return parser_qexpr(result); } else{ tree = new_tree(); ast_tag(tree,"expr"); return parser_sym(tree, t->sym); } } }
// 分析 qexpr ast_tree *parser_qexpr(token_result *result) { token *t; ast_tree *tree = new_tree(), *temp; ast_tag(tree, "qexpr"); //读取引号 t = next_token(result); ast_tree_add(tree, parser_char(t->sym)); //检查是否为Q_EXPR t = next_token(result); if( t->type != TOKEN_SYM || strcmp(t->sym, "(") != 0) return parser_err("QEXPRSSION miss left brace"); else ast_tree_add(tree, parser_char(t->sym)); while((t = next_token(result))){ if(t->type == TOKEN_SYM && strcmp(t->sym, ")") == 0){ ast_tree_add(tree, parser_char(t->sym)); return tree; } putback_token(); temp = parser_expr(result); if(strstr(temp->tag, "error")) return temp; ast_tree_add(tree, temp); } return parser_err("miss the back quote!"); }
/* Read a list. The opening '(' has already been read when this is called. */ static sexpr *readlist(IC *ic) { char *token = gettoken(ic->r); if(token == NULL) return ic->eof; if(!strcmp(token, ")")) return ic->g_nil; if(!strcmp(token, ".")) { sexpr *tmp = readobj(ic); token = gettoken(ic->r); if(token == NULL) return ic->eof; if(strcmp(token, ")")) return ic->g_nil; return tmp; } putback_token(ic->r, token); sexpr *first = readobj(ic); /* Must force evaluation order */ protect_ptr(ic->g, (void **) &first); sexpr *rest = readlist(ic); protect_ptr(ic->g, (void **) &rest); sexpr *ret = cons(ic, first, rest); unprotect_ptr(ic->g); unprotect_ptr(ic->g); return ret; }
//分析 sexpr ast_tree *parser_sexpr(token_result *result) { token *t; ast_tree *tree = new_tree(), *temp; ast_tag(tree, "sexpr"); //读取前括号 t = next_token(result); ast_tree_add(tree, parser_char(t->sym)); while((t = next_token(result))){ if(t->type == TOKEN_SYM && strcmp(t->sym, ")") == 0){ ast_tree_add(tree, parser_char(t->sym)); return tree; } putback_token(); temp = parser_expr(result); //出错则直接返回 if(strstr(temp->tag, "error")) return temp; ast_tree_add(tree, temp); } return parser_err("miss the back quote!"); }