/*********************************************************************/ /* pC++/Sage++ Copyright (C) 1993,1995 */ /* Indiana University University of Oregon University of Rennes */ /*********************************************************************/ /* Created By Jenq-Kuen Lee April 14, 1988 */ /* A Sub-program to help yylex() catch all the comments */ /* A small finite automata used to identify the input token corresponding to */ /* Bif node position */ #include #include "vparse.h" #include "vpc.h" #include "db.h" #include "vextern.h" #include "annotate.tab.h" extern void Message(char *s, int l); void reset_semicoln_handler(); void reset(); int class_struct(int value); int is_declare(int value); int declare_symb(int value); int block_like(int state); int keep_original(int state); int lastdecl_id; /* o if no main_type appeared */ int left_paren ; static int cur_state ; int cur_counter; struct { PTR_CMNT stack[MAX_NESTED_SIZE]; int counter[MAX_NESTED_SIZE]; int node_type[MAX_NESTED_SIZE]; int automata_state[MAX_NESTED_SIZE]; int top ; } comment_stack ; struct { PTR_CMNT stack[MAX_NESTED_SIZE + 1 ]; int front ; int rear ; } comment_queue; struct { int line_stack[MAX_NESTED_SIZE + 1 ]; PTR_FNAME file_stack[MAX_NESTED_SIZE + 1 ]; int front ; int rear ; int BUGGY[100]; /* This is included because some versions of gcc seemed to have bugs that overwrite previous fields without. */ } line_queue; PTR_FNAME find_file_entry() { /* dummy, should not be use after cleaning */ return NULL; } void put_line_queue(line_offset,name) int line_offset ; char *name; { PTR_FNAME find_file_entry(); if (line_queue.rear == MAX_NESTED_SIZE) line_queue.rear = 0; else line_queue.rear++; if (line_queue.rear == line_queue.front) Message("stack/queue overflow",0); line_queue.line_stack[line_queue.rear] = line_offset ; line_queue.file_stack[line_queue.rear] = find_file_entry(name); } PTR_FNAME fetch_line_queue(line_ptr ) int *line_ptr; { if (line_queue.front == line_queue.rear) { *line_ptr = line_queue.line_stack[line_queue.front] ; return(line_queue.file_stack[line_queue.front]); } if (line_queue.front == MAX_NESTED_SIZE) line_queue.front = 0; else line_queue.front++; *line_ptr = line_queue.line_stack[line_queue.front] ; return(line_queue.file_stack[line_queue.front]); } void push_state() { comment_stack.top++; comment_stack.stack[ comment_stack.top ] = cur_comment ; comment_stack.counter[ comment_stack.top ] = cur_counter ; comment_stack.automata_state[ comment_stack.top ] = cur_state ; } void pop_state() { cur_comment = comment_stack.stack[ comment_stack.top ] ; cur_counter = comment_stack.counter[ comment_stack.top ] ; cur_state = comment_stack.automata_state[ comment_stack.top ] ; comment_stack.top--; } void init_stack() { comment_stack.top = 0 ; comment_stack.automata_state[ comment_stack.top ] = ZERO; } void automata_driver(value) int value ; { int shift_flag ; int temp_state ; for (shift_flag = ON ; shift_flag==ON ; ) { shift_flag = OFF ; switch(cur_state) { case ZERO : switch (value) { case IF : put_line_queue(line_pos_1,line_pos_fname); cur_state = IF_STATE; break ; case ELSE : put_line_queue(line_pos_1,line_pos_fname); cur_state = ELSE_EXPECTED_STATE ; break; case DO : put_line_queue(line_pos_1,line_pos_fname); cur_state = DO_STATE ; break; case FOR : put_line_queue(line_pos_1,line_pos_fname); cur_state = FOR_STATE ; break; case CASE : case DEFAULT_TOKEN: put_line_queue(line_pos_1,line_pos_fname); cur_state = CASE_STATE; break; case GOTO : put_line_queue(line_pos_1,line_pos_fname); cur_state = GOTO_STATE; break; case WHILE : put_line_queue(line_pos_1,line_pos_fname); cur_state = WHILE_STATE; break; case SWITCH: put_line_queue(line_pos_1,line_pos_fname); cur_state = SWITCH_STATE; break; case COEXEC : cur_state = COEXEC_STATE ; put_line_queue(line_pos_1,line_pos_fname); break; case COLOOP: put_line_queue(line_pos_1,line_pos_fname); cur_state = COLOOP_STATE ; break; case RETURN: put_line_queue(line_pos_1,line_pos_fname); cur_state = RETURN_STATE ; break; case '}': pop_state(); switch (cur_state) { case ELSE_EXPECTED_STATE: put_line_queue(line_pos_1,line_pos_fname); break; case STATE_4: case BLOCK_STATE: put_line_queue(line_pos_1,line_pos_fname); reset(); reset_semicoln_handler(); break; case IF_STATE_4: cur_state= ELSE_EXPECTED_STATE; put_line_queue(line_pos_1,line_pos_fname); break; case DO_STATE_1: cur_state= DO_STATE_2; reset_semicoln_handler(); break; case DO_STATE_2: case STATE_2: break; default: reset(); reset_semicoln_handler(); } break ; case '{': temp_state=comment_stack.automata_state[comment_stack.top]; if (temp_state == STATE_ARG) comment_stack.automata_state[comment_stack.top]= STATE_4; else { cur_state = BLOCK_STATE ; put_line_queue(line_pos_1,line_pos_fname); push_state(); } reset(); break ; case '(': put_line_queue(line_pos_1,line_pos_fname); cur_state = STATE_15; left_paren++; break; case IDENTIFIER: put_line_queue(line_pos_1,line_pos_fname); cur_state = STATE_6 ; break; case ';': reset_semicoln_handler(); break; default : /* other */ put_line_queue(line_pos_1,line_pos_fname); if (class_struct(value)) cur_state = STATE_10 ; else cur_state = STATE_1 ; break; } break; case STATE_1 : if (value == '(') { cur_state =STATE_15 ; left_paren++; } if (class_struct(value)) cur_state =STATE_10 ; if (value == IDENTIFIER) cur_state =STATE_2 ; if (value == OPERATOR) cur_state =STATE_4 ; if (value ==';') reset_semicoln_handler(); break ; case STATE_2 : if (value == '(') { cur_state = STATE_15 ; left_paren++; } if (value ==';') { reset(); reset_semicoln_handler(); } break; case STATE_4: switch (value) { case '(': cur_state = STATE_15 ; left_paren++; break; case '{': /* cur_state = STATE_5; */ push_state(); reset(); break; case '=': case ',': cur_state = STATE_12; break; case ';': reset_semicoln_handler(); break; default: if (is_declare(value)) { cur_state = STATE_ARG ; push_state(); reset(); } else cur_state = STATE_12; } break; case STATE_6: if (value == ':') cur_state = ZERO; else { if (value ==';') reset_semicoln_handler(); else { cur_state = STATE_2; shift_flag = ON ; } } break; case STATE_10 : if (value =='{') { cur_state = STATE_2 ; push_state(); reset(); } if ((value == '=' )||(value ==',')) cur_state = STATE_12; if (value == '(' ) { cur_state = STATE_15; left_paren++; } if (value ==';') reset_semicoln_handler(); break ; case STATE_12: if (value ==';') reset_semicoln_handler(); break ; case STATE_15 : if (value == '(') left_paren++ ; if (value == ')') left_paren--; if (left_paren == 0) cur_state = STATE_4 ; break ; case IF_STATE: if (value == '(') { left_paren++; cur_state = IF_STATE_2; } break; case IF_STATE_2: if (value == '(') left_paren++ ; if (value == ')') left_paren--; if (left_paren == 0) cur_state = IF_STATE_3 ; break ; case IF_STATE_3: if (value == ';') { put_line_queue(line_pos_1,line_pos_fname); cur_state= ELSE_EXPECTED_STATE ; } if (value =='{') { cur_state= ELSE_EXPECTED_STATE ; push_state(); cur_state = ZERO ; /* counter continuing */ } if (cur_state == IF_STATE_3) { cur_state = IF_STATE_4 ; push_state(); reset(); shift_flag = ON; } break; case ELSE_EXPECTED_STATE: if (value == ELSE) cur_state = BLOCK_STATE ; else { reset(); reset_semicoln_handler(); shift_flag = ON ; } break; case BLOCK_STATE: if (value ==';') { cur_state = BLOCK_STATE_WAITSEMI; push_state(); reset_semicoln_handler(); } if (value == '{') { push_state(); reset(); } if (cur_state == BLOCK_STATE) { cur_state = BLOCK_STATE_WAITSEMI; push_state(); reset(); shift_flag = ON ; } break; case WHILE_STATE: if (value == '('){ left_paren++; cur_state = WHILE_STATE_2; } break; case WHILE_STATE_2: if (value == '(') left_paren++ ; if (value == ')') left_paren--; if (left_paren == 0) cur_state = BLOCK_STATE ; break ; case FOR_STATE: if (value == '(') { left_paren++; cur_state = FOR_STATE_2; } break; case FOR_STATE_2: if (value == '(') left_paren++ ; if (value == ')') left_paren--; if (left_paren == 0) cur_state = BLOCK_STATE ; break ; case COLOOP_STATE: if (value == '(') { left_paren++; cur_state = COLOOP_STATE_2; } break; case COLOOP_STATE_2: if (value == '(') left_paren++ ; if (value == ')') left_paren--; if (left_paren == 0) cur_state = BLOCK_STATE ; break ; case COEXEC_STATE: if (value == '(') { left_paren++; cur_state = COEXEC_STATE_2; } break; case COEXEC_STATE_2: if (value == '(') left_paren++ ; if (value == ')') left_paren--; if (left_paren == 0) cur_state = BLOCK_STATE ; break ; case SWITCH_STATE: if (value == '(') { left_paren++; cur_state = SWITCH_STATE_2; } break; case SWITCH_STATE_2: if (value == '(') left_paren++ ; if (value == ')') left_paren--; if (left_paren == 0) cur_state = BLOCK_STATE ; break ; case CASE_STATE : if (value == ':') reset(); break; case DO_STATE : /* Need More, some problem exists */ if (value == ';') { cur_state = DO_STATE_2 ; } if (value == '{') { cur_state = DO_STATE_2 ; push_state(); reset(); } if (cur_state == DO_STATE) { cur_state = DO_STATE_1 ; push_state(); reset(); shift_flag = ON; } break; case DO_STATE_2: if (value == WHILE) cur_state= DO_STATE_3 ; break ; case DO_STATE_3: if (value == '(') { cur_state = DO_STATE_4 ; left_paren++; } break; case DO_STATE_4: if (value == '(') left_paren++ ; if (value == ')') left_paren--; if (left_paren == 0) cur_state = DO_STATE_5 ; break ; case DO_STATE_5: if (value ==';') { put_line_queue(line_pos_1,line_pos_fname); reset(); reset_semicoln_handler(); } break; case RETURN_STATE: if (value ==';') reset_semicoln_handler(); if (value == '(') { left_paren++; cur_state = RETURN_STATE_2 ; } break; case RETURN_STATE_2: if (value == '(') left_paren++ ; if (value == ')') left_paren--; if (left_paren == 0) cur_state = RETURN_STATE_3 ; break ; case RETURN_STATE_3: if (value ==';') reset_semicoln_handler(); break; case GOTO_STATE: if (value == IDENTIFIER) cur_state = GOTO_STATE_2 ; break; case GOTO_STATE_2: if (value ==';') reset_semicoln_handler(); break; default: Message(" comments state un_expected...",0); break; } } } int class_struct(int value) { switch (value) { case ENUM : case CLASS: case STRUCT : case UNION: return(1); default : return(0); } } int declare_symb(int value) { switch (value) { case TYPENAME : case TYPESPEC: case TYPEMOD: case ACCESSWORD: case SCSPEC: case ENUM : case CLASS: case STRUCT : case UNION: return(1); default : return(0); } } void reset() { cur_state = 0 ; cur_counter = 0 ; cur_comment = (PTR_CMNT) NULL ; /* put_line_queue(line_pos_1,line_pos_fname); */ } int block_like(int state) { switch( state) { case BLOCK_STATE: case ZERO: case SWITCH_STATE: case FOR_STATE : case WHILE_STATE : case COEXEC_STATE : case COLOOP_STATE: case STATE_4: /* end of function_body */ return(1); default: return(0); } } int is_declare(int value) { switch (value) { case TYPENAME: case TYPESPEC : case ACCESSWORD: case SCSPEC: case TYPEMOD: case ENUM: case UNION: case CLASS: case STRUCT: return(1); default : return(0); } } /* pop state until reach a stable state BLOCK_STATE or ZERO */ void reset_semicoln_handler() { int sw,state; for (sw=1; sw; ) { if (keep_original(cur_state)) return; state = comment_stack.automata_state[comment_stack.top]; switch (state) { case IF_STATE_4: pop_state(); cur_state = ELSE_EXPECTED_STATE ; put_line_queue(line_pos_1,line_pos_fname); break; case DO_STATE_1: pop_state(); cur_state = DO_STATE_2 ; break; case BLOCK_STATE_WAITSEMI: put_line_queue(line_pos_1,line_pos_fname); pop_state(); reset(); break; default : reset(); sw = 0 ; } } } int keep_original(int state) { switch (state) { case ELSE_EXPECTED_STATE: case DO_STATE_2: case STATE_2: return(1); default: return(0); } } /*****************************************************************************/ /* is_at_decl_state() & is_look_ahead_of_identifier() */ /* These two routines are used in yylex to identify if a TYPENAME is just */ /* a IDENTIFIER */ /* */ /*****************************************************************************/ int is_at_decl_state() { /* to see if it is inside (, ) */ switch(cur_state) { case STATE_15: case IF_STATE_2: case WHILE_STATE_2: case FOR_STATE_2: case COLOOP_STATE_2: case COEXEC_STATE_2: case SWITCH_STATE_2: case DO_STATE_4: return(0); default: return(1); } } int is_look_ahead_of_identifier(c) char c; { switch (c) { case ':' : case '(': case '[': case ',': case ';': case '=': return(1); default: return(0); } } void set_up_momentum(value,token) int value,token; { if (lastdecl_id == 0) { /* check if main_type appears */ switch (value) { case TYPESPEC: lastdecl_id = 1; break; case TYPEMOD: if ((token == (int)RID_LONG)||(token == (int)RID_SHORT)|| (token==(int)RID_SIGNED)||(token==(int)RID_UNSIGNED)) lastdecl_id = 1; break; } } else { /* case for main_type already appear, then check if 1. this is still a decl. 2. reset it to wait for another decl stat. */ switch (value) { case TYPESPEC: case TYPEMOD: case SCSPEC: break; default: lastdecl_id = 0; } } }