void if_stat(){ match(IF); expr(); match(THEN); stat_list(); if (lookahead == ELSE){ match(ELSE); stat_list(); } match(END); }
/*Controlla la semantica del nodo while e ne restituisce il codice*/ Code while_stat(Pnode while_stat_node){ //Imposto le due parti del nodo Pnode expr_node = while_stat_node->child; Pnode stat_list_node = while_stat_node->child->brother; //Definisco la variabile che contiene il codice da ritornare Code while_stat_code; //La generazione dell'ambiente viene fatta all'interno della funzione stat_list //Genero il codice di expr Pschema schema_expr = (Pschema) newmem(sizeof(Schema)); Code expr_code = expr(expr_node,schema_expr); //Controllo i vincoli semantici if (schema_expr->type!=BOOLEAN) semerror(expr_node,"Expected boolean type"); //Genero il codice di stat_list Code stat_list_code = stat_list(stat_list_node); //Calcolo gli offset int exit = stat_list_code.size + 2; int up = -(expr_code.size + stat_list_code.size + 1); //Genero il codice di while_stat while_stat_code = concode(expr_code,makecode1(T_SKIPF,exit),stat_list_code,makecode1(T_SKIP,up),endcode()); return while_stat_code; }
void while_stat(){ match(WHILE); expr(); match(DO); stat_list(); match(END); }
/*Controlla la semantica del nodo if e ne ritorna il codice*/ Code if_stat(Pnode if_stat_node){ #ifdef DEBUG_IF_STAT printf("IF_STAT - enter\n"); #endif //Imposto le tre parti del nodo Pnode expr_node = if_stat_node->child; Pnode then_node = if_stat_node->child->brother; Pnode else_node = if_stat_node->child->brother->brother; //Definisco la variabile che contiene il codice da ritornare Code if_stat_code ; //La generazione dell'ambiente viene fatta all'interno della funzione stat_list //Genero il codice di expr Pschema schema_expr = (Pschema) newmem(sizeof(Schema)); Code expr_code = expr(expr_node,schema_expr); //Controllo i vincoli semantici if (schema_expr->type!=BOOLEAN) semerror(expr_node,"Expected boolean type"); //Genero il codice di then_node Code then_code = stat_list(then_node); if (else_node==NULL){//if then endif //Calcolo l'offset int offset = then_code.size + 1; //Genero il codice di if_stat if_stat_code = concode(expr_code,makecode1(T_SKIPF,offset),then_code,endcode()); } else {//if then else //Genero il codice di else_node Code else_code = stat_list(else_node); //Calcolo gli offset int offset_then = then_code.size + 2; int offset_else = else_code.size + 1; //Genero il codice di if_stat if_stat_code = concode(expr_code,makecode1(T_SKIPF,offset_then),then_code,makecode1(T_SKIP,offset_else),else_code,endcode()); } #ifdef DEBUG_IF_STAT printf("IF_STAT - exit\n"); #endif return if_stat_code; }
Code program(Pnode root) { Code body = stat_list(root->child); Value v1; v1.ival = body.size + 2; return concode(makecode1(T_TCODE, v1), body, makecode(T_HALT), endcode()); }
Code if_stat(Pnode p) { /* if / / expr ---> stat_list [---> stat_list] */ Schema exprschema; Code exprcode = expr(p->child, &exprschema); Code bodythen = stat_list(p->child->brother); // Vincoli semantici if (exprschema.type != BOOLEAN) semerror(p->child, "Boolean expression required"); if (p->child->brother->brother == NULL) { // IF-THEN Value v1; v1.ival = bodythen.size + 1; return concode(exprcode, makecode1(T_SKIPF, v1), bodythen, endcode()); } else { // IF-THEN-ELSE Code bodyelse = stat_list(p->child->brother->brother); Value v1; v1.ival = bodythen.size + 2; Value v2; v2.ival = bodyelse.size + 1; return concode(exprcode, makecode1(T_SKIPF, v1), bodythen, makecode1(T_SKIP, v2), bodyelse, endcode() ); } }
// [RULE] stat: list EOF | assign EOF; void stat() { // check if stat is a list if (stat_list()) { list(); match(EOF_TYPE); } // check if stat is an assignment else if (stat_assign()) { assign(); match(EOF_TYPE); } else throw NoViableAltException(lookaheadType(1)); }
void stat_shutdown(struct pk_state *state, gboolean normal) { gchar **stats; gchar **cur; gchar *value; if (normal) { /* Log statistics */ for (stats = cur = stat_list(state); *cur != NULL; cur++) { value = stat_get(state, *cur); g_strchomp(value); pk_log(LOG_STATS, "%s: %s", *cur, value); g_free(value); } g_strfreev(stats); } g_hash_table_destroy(state->fuse->stat_buffers); g_mutex_free(state->fuse->stat_buffer_lock); }
Code while_stat(Pnode p) { /* while / / expr ---> stat_list */ Schema exprschema; Code exprcode = expr(p->child, &exprschema); Code body = stat_list(p->child->brother); // Vincoli semantici if (exprschema.type != BOOLEAN) semerror(p->child, "Boolean expression required"); Value v1; v1.ival = body.size + 2; Value v2; v2.ival = -(exprcode.size + body.size + 1); return concode(exprcode, makecode1(T_SKIPF, v1), body, makecode1(T_SKIP, v2), endcode()); }
//语句 AST_node statement(AST_node parent) { AST_node t = makeNode(STATEMENT, parent); if (symbol == IDENT) { //赋值语句或者过程调用语句 //<赋值语句>::=<标识符>:=<表达式>|<函数标识符>:=<表达式>|<标识符>'['<表达式>']':=<表达式> //<过程调用语句>::=<标识符>[<实在参数表>] match(IDENT,t); if (symbol == BECOMES || symbol == LBRACKET) { //赋值语句 stat_assign(t); } else if (symbol == LPARENT || symbol == SEMICOLON || symbol == END //过程调用语句在end前,可以没有分号 ) { //过程调用语句 stat_procedure(t); } else { error("Unknown Statement!"); recovery(2, SEMICOLON, END); } } else if (symbol == IF) { //条件语句 //<条件语句>::=if<条件>then<语句>|if<条件>then<语句>else<语句> stat_if(t); } else if (symbol == DO) { //当循环语句 //<当循环语句>::=do<语句>while<条件> stat_do(t); } else if (symbol == FOR) { //for循环语句 //<for循环语句>::=for<标识符>:=<表达式>(downto|to)<表达式>do<语句>//步长为1 stat_for(t); } else if (symbol == BEGIN) { //复合语句 //<复合语句>::=begin<语句>{;<语句>}end stat_list(t); } else if (symbol == READ) { //读语句 //<读语句>::=read'('<标识符>{,<标识符>}')' stat_read(t); } else if (symbol == WRITE) { //写语句 //<写语句>::=write'('<字符串>,<表达式>')'|write'('<字符串>')'|write'('<表达式>')' stat_write(t); } else { //空语句 t->ast_type = EMPTY; printf("----------------Empty Statement--------------\n"); } return 0; }
/*Genera il codice per il nodo program*/ Code program(Pnode root){ Code body = stat_list(root->child); //Prende body, gli mette TCODE prima e THALT dopo. return concode(makecode1(T_TCODE, body.size + 2), body, makecode(T_HALT), endcode()); }
void program(){ match(PROGRAM); stat_list(); match(END); match(END_OF_FILE); //end of file }