📄 parse.c
字号:
break_comma = false; /* don't break comma in an initial list */ if (parser_state_tos->p_stack[parser_state_tos->tos] == stmt || parser_state_tos->p_stack[parser_state_tos->tos] == stmtl) { /* it is a random, isolated stmt group or a declaration */ parser_state_tos->i_l_follow += settings.ind_size; } else if (parser_state_tos->p_stack[parser_state_tos->tos] == decl) { parser_state_tos->i_l_follow += settings.ind_size; if ( ( (parser_state_tos->last_rw == rw_struct_like) || (parser_state_tos->last_rw == rw_enum)) && ( (parser_state_tos->block_init != 1) || (parser_state_tos->block_init_level == 0)) && (parser_state_tos->last_token != rparen) && (!settings.braces_on_struct_decl_line)) { parser_state_tos->ind_level += settings.struct_brace_indent; parser_state_tos->i_l_follow += settings.struct_brace_indent; } } else if (parser_state_tos->p_stack[parser_state_tos->tos] == casestmt) { parser_state_tos->ind_level += settings.case_brace_indent - settings.ind_size; parser_state_tos->i_l_follow += settings.case_brace_indent; } else { /* It is a group as part of a while, for, etc. */ /* Only do this if there is nothing on the line */ if (s_code == e_code) { parser_state_tos->ind_level -= settings.ind_size; } /* For -bl formatting, indent by settings.brace_indent additional spaces * e.g. if (foo == bar) { <--> settings.brace_indent spaces (in this * example, 4) */ if (!settings.btype_2) { parser_state_tos->ind_level += settings.brace_indent; parser_state_tos->i_l_follow += settings.brace_indent; } if (parser_state_tos->p_stack[parser_state_tos->tos] == swstmt) { parser_state_tos->i_l_follow += settings.case_indent; } } inc_pstack (); parser_state_tos->p_stack[parser_state_tos->tos] = lbrace; parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->ind_level; inc_pstack (); parser_state_tos->p_stack[parser_state_tos->tos] = stmt; /* allow null stmt between braces */ parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow; break; case whilestmt: /* scanned while (...) */ if (parser_state_tos->p_stack[parser_state_tos->tos] == dohead) { /* it is matched with do stmt */ parser_state_tos->i_l_follow = parser_state_tos->il[parser_state_tos->tos]; parser_state_tos->ind_level = parser_state_tos->il[parser_state_tos->tos]; inc_pstack (); parser_state_tos->p_stack[parser_state_tos->tos] = whilestmt; parser_state_tos->ind_level = parser_state_tos->i_l_follow; parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow; } else { /* it is a while loop */ inc_pstack (); parser_state_tos->p_stack[parser_state_tos->tos] = whilestmt; parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow; parser_state_tos->i_l_follow += settings.ind_size; parser_state_tos->search_brace = settings.btype_2; } break; case elselit: /* scanned an else */ if (parser_state_tos->p_stack[parser_state_tos->tos] != ifhead) { ERROR (_("Unmatched 'else'"), 0, 0); } else { /* indentation for else should be same as for if */ parser_state_tos->ind_level = parser_state_tos->il[parser_state_tos->tos]; /* everything following should be in 1 level */ parser_state_tos->i_l_follow = (parser_state_tos->ind_level + settings.ind_size); parser_state_tos->p_stack[parser_state_tos->tos] = elsehead; /* remember if with else */ parser_state_tos->search_brace = true; } break; case rbrace: /* scanned a } */ /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */ if (parser_state_tos->p_stack[parser_state_tos->tos - 1] == lbrace) { parser_state_tos->i_l_follow = parser_state_tos->il[--parser_state_tos->tos]; parser_state_tos->ind_level = parser_state_tos->i_l_follow; parser_state_tos->p_stack[parser_state_tos->tos] = stmt; } else { ERROR (_("Stmt nesting error."), 0, 0); } break; case swstmt: /* had switch (...) */ inc_pstack (); parser_state_tos->p_stack[parser_state_tos->tos] = swstmt; parser_state_tos->cstk[parser_state_tos->tos] = settings.case_indent + parser_state_tos->i_l_follow; if (!settings.btype_2) { parser_state_tos->cstk[parser_state_tos->tos] += settings.brace_indent; } /* save current case indent level */ parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow; /* case labels should be one level down from switch, plus * `settings.case_indent' if any. Then, statements should be the `settings.ind_size' * further. */ parser_state_tos->i_l_follow += settings.ind_size; parser_state_tos->search_brace = settings.btype_2; break; case semicolon: /* this indicates a simple stmt */ break_comma = false; /* turn off flag to break after commas in a * declaration */ if (parser_state_tos->p_stack[parser_state_tos->tos] == dostmt) { parser_state_tos->p_stack[parser_state_tos->tos] = stmt; } else { inc_pstack (); parser_state_tos->p_stack[parser_state_tos->tos] = stmt; parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->ind_level; } break; /* This is a fatal error which cases the program to exit. */ default: fatal (_("Unknown code to parser"), 0); } reduce (); /* see if any reduction can be done */#ifdef DEBUG if (debug) { printf ("\n"); printf (_("ParseStack [%d]:\n"), (int) parser_state_tos->p_stack_size); for (i = 1; i <= parser_state_tos->tos; ++i) { printf (_(" stack[%d] => stack: %d ind_level: %d\n"), (int) i, (int) parser_state_tos->p_stack[i], (int) parser_state_tos->il[i]); } printf ("\n"); }#endif return total_success;}/* NAME: reduce * * FUNCTION: Implements the reduce part of the parsing algorithm * * ALGORITHM: The following reductions are done. Reductions are repeated until * no more are possible. * * Old TOS New TOS <stmt> <stmt> <stmtl> <stmtl> <stmt> * <stmtl> do <stmt> dohead <dohead> <whilestmt> * <dostmt> if <stmt> "ifstmt" switch <stmt> <stmt> * decl <stmt> <stmt> "ifelse" <stmt> <stmt> for * <stmt> <stmt> while <stmt> <stmt> * "dostmt" while <stmt> * * On each reduction, parser_state_tos->i_l_follow (the indentation for the * following line) is set to the indentation level associated with the old * TOS. * * PARAMETERS: None * * RETURNS: Nothing * * GLOBALS: parser_state_tos->cstk parser_state_tos->i_l_follow = * parser_state_tos->il parser_state_tos->p_stack = parser_state_tos->tos = * * CALLS: None * * CALLED BY: parse * * HISTORY: initial coding November 1976 D A Willcox of CAC * *//*----------------------------------------------*\| REDUCTION PHASE |\*----------------------------------------------*/void reduce (void){ int i; for (;;) { /* keep looping until there is nothing left to reduce */ switch (parser_state_tos->p_stack[parser_state_tos->tos]) { case stmt: switch (parser_state_tos->p_stack[parser_state_tos->tos - 1]) { case stmt: case stmtl: /* stmtl stmt or stmt stmt */ parser_state_tos->p_stack[--parser_state_tos->tos] = stmtl; break; case dolit: /* <do> <stmt> */ parser_state_tos->p_stack[--parser_state_tos->tos] = dohead; parser_state_tos->i_l_follow = parser_state_tos->il[parser_state_tos->tos]; break; case ifstmt: /* <if> <stmt> */ parser_state_tos->p_stack[--parser_state_tos->tos] = ifhead; for (i = parser_state_tos->tos - 1; ( (parser_state_tos->p_stack[i] != stmt) && (parser_state_tos->p_stack[i] != stmtl) && (parser_state_tos->p_stack[i] != lbrace)); --i) { } parser_state_tos->i_l_follow = parser_state_tos->il[i]; /* for the time being, we will assume that there is no else on * this if, and set the indentation level accordingly. If an * else is scanned, it will be fixed up later */ break; case swstmt: /* <switch> <stmt> */ case decl: /* finish of a declaration */ case elsehead: /* <<if> <stmt> else> <stmt> */ case forstmt: /* <for> <stmt> */ case casestmt: /* <case n:> <stmt> */ case whilestmt: /* <while> <stmt> */ parser_state_tos->p_stack[--parser_state_tos->tos] = stmt; parser_state_tos->i_l_follow = parser_state_tos->il[parser_state_tos->tos]; break; default: /* <anything else> <stmt> */ return; } /* end of section for <stmt> on top of stack */ break; case whilestmt: /* while (...) on top */ if (parser_state_tos->p_stack[parser_state_tos->tos - 1] == dohead) { /* it is termination of a do while */ parser_state_tos->p_stack[--parser_state_tos->tos] = dostmt; break; } else return; default: /* anything else on top */ return; } }}/* This kludge is called from main. It is just like parse(semicolon) except * that it does not clear break_comma. Leaving break_comma alone is * necessary to make sure that "int foo(), bar()" gets formatted correctly * under -bc. */void parse_lparen_in_decl (void){ inc_pstack (); parser_state_tos->p_stack[parser_state_tos->tos] = stmt; parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->ind_level; reduce ();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -