void parse_start_tag(token tag_name, param *param_list) { match_next_file_token(TOKEN_OPEN_TAG); match_next_file_token(tag_name); parse_param_list(tag_name, param_list, TOKEN_CLOSE_TAG); }
/* * Parse statement starting with an identifier. * Possibilities include: * Assignment * Procedure statement */ void parse_identifier(TOKEN *first_token) { TOKEN token, next_token; TOKEN param_token, attrib_token, type_token; int token_class, next_token_class; DECL *decl_list, *extra_decl_list; PARAM_LIST *param_list, *param_ptr; DECL_MEMBER *decl_ptr; DECL_ID *decl_id; BOOLEAN extern_proc, got_type, interrupt_proc; char *tmp_text_ptr; /* Check for label or procedure */ tmp_text_ptr = text_ptr; token_class = get_token(&token); if (token_class == LABEL) { /* Determine if label or procedure definition */ next_token_class = get_token(&next_token); if ((next_token_class == RESERVED) && (next_token.token_type == PROCEDURE)) { /* * Procedure - Check for parameter list */ param_list = NULL; token_class = get_token(¶m_token); if (token_class == LEFT_PAREN) { /* Yes - get parameter list */ get_param_list(¶m_list); /* Get token after parameter list */ token_class = get_token(&attrib_token); } else /* No param list - save as attribute */ token_copy(¶m_token, &attrib_token); out_white_space(first_token); extern_proc = FALSE; interrupt_proc = FALSE; got_type = (token_class == RESERVED) && (attrib_token.token_type >= BYTE) && (attrib_token.token_type <= SELECTOR); if (got_type) { /* * Process [ <type> ] */ token_copy(&attrib_token, &type_token); token_class = get_token(&attrib_token); } while (token_class == RESERVED) { if (attrib_token.token_type == INTERRUPT) { /* * Process [ <interrupt> ] */ interrupt_proc = TRUE; token_class = get_token(&attrib_token); if (token_class == NUMERIC) /* Interrupt number */ token_class = get_token(&attrib_token); } else /* * Process [ EXTERNAL | { [ PUBLIC ] [ REENTRANT ] } ] */ if (attrib_token.token_type == EXTERNAL) { out_str("extern"); out_must_white(&attrib_token); extern_proc = TRUE; token_class = get_token(&attrib_token); } else if ((attrib_token.token_type == PUBLIC) || (attrib_token.token_type == REENTRANT)) { do { if (attrib_token.token_type == PUBLIC) { /* Ignore for now */ token_class = get_token(&attrib_token); } else if (attrib_token.token_type == REENTRANT) { /* Ignore for now */ token_class = get_token(&attrib_token); } else break; } while (token_class == RESERVED); } else break; } if (token_class != END_OF_LINE) { parse_error("';' expected"); return; } if (interrupt_proc && !extern_proc) parse_warning("INTERRUPT procedure declared"); /* Create declaration for procedure */ get_element_ptr(&decl_ptr); get_var_ptr(&decl_ptr->name_list); /* Type = PROCEDURE */ get_token_ptr(&decl_ptr->type); token_copy(&next_token, decl_ptr->type); /* Name = procedure name */ get_token_ptr(&decl_ptr->name_list->name); token_copy(first_token, decl_ptr->name_list->name); /* Flag if parameter list */ if (param_list) decl_ptr->initialization = DATA; /* Add it to context */ add_to_context(decl_ptr); if (got_type) { /* Output procedure type */ out_token_name(&type_token); out_must_white(&type_token); } /* Output procedure name */ out_token_name(first_token); if (extern_proc) { out_str("()"); if (param_list) /* Parse parameter declarations */ parse_param_list(param_list, &decl_list, &extra_decl_list); out_char(';'); /* Eat closing 'END [<proc name>];' */ token_class = get_token(&token); if ((token_class != RESERVED) || (token.token_type != END)) { parse_error("END expected"); return; } out_white_space(&token); token_class = get_token(&token); if (token_class == IDENTIFIER) { token_class = get_token(&token); } if (token_class != END_OF_LINE) { parse_error("';' expected"); } return; } else if (param_list) { out_token(¶m_token); /* Output parameter list */ param_ptr = param_list; while (param_ptr) { out_token(¶m_ptr->param); param_ptr = param_ptr->next_param; if (param_ptr) out_char(','); } out_char(')'); /* Parse parameter declarations */ parse_param_list(param_list, &decl_list, &extra_decl_list); /* Output declarations */ if (decl_list) { out_decl(decl_list); /* Add declarations to context */ add_decl_to_context(decl_list); } out_str("\n{"); /* } for dumb vi */ if (extra_decl_list) { out_decl(extra_decl_list); /* Add declarations to context */ add_decl_to_context(extra_decl_list); } /* Discard declarations */ free_decl(decl_list); free_decl(extra_decl_list); } else /* No parameter list */ out_str("()\n{"); /* } for dumb vi */ /* Create new context */ new_context(PROCEDURE, first_token); /* Parse statements to END */ parse_to_end(); /* Pop procedure context */ pop_context(); } else { /* * Label - add label name */ out_token(first_token); /* Add colon */ out_token(&token); /* Is this a defined label or a module? */ if (find_symbol(first_token, &decl_ptr, &decl_id)) { if (decl_ptr->type->token_class == LABEL) { /* Label - new context */ new_context(MODULE, first_token); parse_statement(&next_token); pop_context(); } else { parse_error("Illegal label name"); return; } } else parse_statement(&next_token); } return; } /* Assignment statement */ text_ptr = tmp_text_ptr; token_copy(first_token, &token); token_class = parse_variable(&token, &decl_ptr, &decl_id); /* Check for multiple assignments */ while (token_class == COMMA) { /* Print ' =' instead of ',' */ out_str(" ="); out_white_space(&token); /* Get identifier part of next assignment variable */ token_class = get_token(&token); if (token_class != IDENTIFIER) { parse_error("Illegal assignment"); return; } /* Parse remainder of variable (if any) */ token_class = parse_variable(&token, &decl_ptr, &decl_id); } if (token_class == OPERATOR) { if (token.token_type != EQUAL) { parse_error("Illegal use of identifier"); return; } out_token(&token); /* Check for POINTER assignment */ if (decl_ptr->type->token_type == POINTER) { /* Yes - cast it */ out_str(" ("); out_str(TYPE_POINTER); out_str(" *) "); } if (parse_expression(&token) != END_OF_LINE) parse_error("';' expected"); else out_token(&token); return; } else if (token_class != LABEL) { parse_error("Illegal use of identifier"); return; } }
tag * parse_next_tag(tag *tag_list, token end_tag_name, char *end_tag_name_str) { int tag_index; token tag_name; char tag_name_str[256]; // Parse start and single tags until a valid tag is found. while (true) { // If the next token is "<" or "</" then there is a tag to be parsed; // any other token is simply ordinary text and must be skipped. switch (next_file_token()) { // If this is a start or single tag, then parse it. case TOKEN_OPEN_TAG: // Read the tag name token. If it is a string token, this is an // error. tag_name = next_file_token(); if (tag_name == VALUE_STRING) file_error("a tag name"); strcpy(tag_name_str, file_token_str); // If a tag list was specified, attempt to match the tag name // against the entries of the tag list. If a match is found, parse // the parameter list for that tag and then return TRUE. if (tag_list) { tag_index = 0; while (tag_list[tag_index].tag_name != TOKEN_NONE) { if (tag_name == tag_list[tag_index].tag_name) { parse_param_list(tag_name, tag_list[tag_index].param_list, tag_list[tag_index].end_token); return(&tag_list[tag_index]); } tag_index++; } } // Otherwise treat this tag as having no parameters, and skip over // any parameters found in this tag. parse_param_list(tag_name, NULL, TOKEN_NONE); // If this was a start tag, recursively call this function without // a tag list to skip over all tags in the content up to and // including the matching end tag. if (file_token == TOKEN_CLOSE_TAG) parse_next_tag(NULL, tag_name, tag_name_str); break; // If the token is "</", then verify we have the expected end tag and // return FALSE, otherwise flag an error. case TOKEN_OPEN_END_TAG: read_next_file_token(); if ((end_tag_name == TOKEN_UNKNOWN && stricmp(file_token_str, end_tag_name_str)) || (end_tag_name != TOKEN_UNKNOWN && end_tag_name != file_token)) file_error("found end tag '%s' with no matching start tag", file_token_str); match_next_file_token(TOKEN_CLOSE_TAG); return(NULL); } } // Required to shut up compiler... return(NULL); }