// file: $isip/class/asr/JSGFParser/jp_08.cc // version: $Id: jp_08.cc 10499 2006-03-15 21:43:17Z may $ // // isip include files // #include "JSGFParser.h" // method: replaceRuleReference // // arguments: JSGFToken& rulename_a: (inoput) a given rule reference name // Stack replaced_rules_a: (input) replaced rule vector // return: a bool8 value indicating status // // This method takes a JSGF rule expansion and recursively replace all // the rule references with the actual matching rules until only terminal // symbols can be found in the rule expansion without any reference. // bool8 JSGFParser::replaceRuleReference(JSGFToken& rulename_a, Stack& replaced_rules_a) { bool8 is_processed = false; processed_rules_d.concat(rulename_a); // store the input rulename in order to be checked for // the potential right recursion // replaced_rules_a.push(&rulename_a.rulename_d); // get the corresponding rule expansion of the input rulename // Vector rule; resolveReference(rulename_a.rulename_d, rule); GraphVertex* curr_vert; int32 index = 0; // bool8 is_graph_term = false; String term_rule_name; term_rule_name.assign(rulename_a.rulename_d); // loop through the rule expansion and replace all rule references // while (index < rule.length()) { JSGFToken current = rule(index); // add all non-rulename token into the class-protected final token queue // if (current.getTokenType() != JSGFToken::RULE_NAME) { // setting the index of vertex in corresponding vertex list of graph // if ((current.getTokenType() == JSGFToken::TERMINAL || current.getTokenType() == JSGFToken::QUOTED_TOKEN) && current.vertex_index_d == -1) { // if the token is the reserved ISIP graph starting or ending symbol // set the vertex as the default graph start or term accordingly // if (current.terminal_d.eq(graph_start_d)) { curr_vert = graph_d.getStart(); } else if (current.terminal_d.eq(graph_term_d)) { curr_vert = graph_d.getTerm(); } // otherwise, create a vertex for the current token // else { curr_vert = graph_d.insertVertex(¤t.terminal_d); bool8 isExist = false; for(int i = 0; i < symbol_list_d.length(); i++) { if(symbol_list_d(i).eq(current.terminal_d)) { isExist = true; break; } } if(!isExist) symbol_list_d.concat(current.terminal_d); } // store this vertex into the vertex list // vertex_list_d[vertex_list_index_d] = curr_vert; current.setTermRuleName(term_rule_name); current.setVertexIndex(vertex_list_index_d); setVertexIndex(current); vertex_list_index_d++; } else if (current.operator_d(0).eq(L")")) { if(replaced_rules_a.contains(¤t.term_rule_name_d)) { String tmp1; String * tmp2; replaced_rules_a.pop(&tmp1); tmp2 = replaced_rules_a.peek(); term_rule_name.assign(*tmp2); } } final_d.add(¤t); } // else, the token is a rulename suggesting a rule reference // else { // first check if a right recursion is formed with // the current rule reference // bool8 recursion = false; // if the current rule reference forms a right recursion to // a previously processed rule // if(replaced_rules_a.contains(¤t.rulename_d)) { // create a marker "@@" token to indicate this right recursion // JSGFToken recur_marker; recur_marker.setMarker(L"@@", current); // add it into the final queue // final_d.add(&recur_marker); //col_index++; // update the bool8 status // recursion = true; } // if no right recursion is found, the current rule reference needs // to be replaced by its corresponding rule expansion // if (!recursion) { // add a "(" left brace for starting a rule extension // JSGFToken left, right; Vector head, tail; for(int32 i = index + 1; i < rule.length(); i++) { tail.concat(rule(i)); } left.setToken(L"("); head.concat(left); index = 0; final_d.add(&left); is_processed = false; // if the current rule is a previously processed rule // for (int32 i = 0; i < processed_rules_d.length(); i++) { if(current.rulename_d.eq(processed_rules_d(i).rulename_d)) { is_processed = true; } } // store the input rulename in order to be checked for unique terminals // if(!is_processed) processed_rules_d.concat(current); replaced_rules_a.push(¤t.rulename_d); // get the corresponding rule expansion of the input rulename // Vector rule1; resolveReference(current.rulename_d, rule1); head.concat(rule1); term_rule_name.assign(current.rulename_d); // add a ")" close brace for closing the rule extension // right.setToken(L")"); right.setTermRuleName(current.rulename_d); head.concat(right); rule.clear(); rule.concat(head); rule.concat(tail); } } // end: if (current.getTokenType() != 4) else structure index++; } // end: while(index < rule.length()) // gracefully exit // return true; } // method: resolveReference // // arguments: // const JSGFToken& rulename_a: (inoput) a given rule reference name // Vector& rule_exp_a: (output) a rule expansion corresponding // to the input rulename // // return: a bool8 value indicating status // // This method checks out a rule expansion from the rule tables according to // the input rulename // bool8 JSGFParser::resolveReference(String& rulename_a, Vector& rule_exp_a) { // bool8 variable to check if the rule expansion is found // bool8 found = false; // pick up the rule expansion from the private rule table according to // the input rulename // for (int32 i = 0; i < private_rule_table_d.length(); i++) { JSGFToken t = private_rule_table_d(i).first(); // copy the rule expansion if the rulename is found // if (rulename_a.eq(t.rulename_d)) { rule_exp_a = private_rule_table_d(i).second(); found = true; break; } } // if the rule expansion cannot be found in the private rule table, // search it in the public rule table // if (!found) { for (int32 i = 0; i < public_rule_table_d.length(); i++) { JSGFToken t = public_rule_table_d(i).first(); // copy the rule expansion if the rulename is found // if (rulename_a.eq(t.rulename_d)) { rule_exp_a = public_rule_table_d(i).second(); found = true; break; } } } // end: if (!found) // error if the rule expansion cannot be found in either of the rule tables // if (!found) { String output(L"referred rule <"); output.concat(rulename_a); output.concat(L"> not found"); return Error::handle(name(), output, Error::TEST, __FILE__, __LINE__); } // gracefully exit // return true; } // method: setVertexIndex // // arguments: // JSGFToken& token_a: (input) a given token // // return: a bool8 value indicating status // // This method set the index of graph vertex list for corresponding terminal // token in the rule // bool8 JSGFParser::setVertexIndex(JSGFToken& token_a) { // bool8 variable to check if the rule expansion is found // bool8 found = false; // a rule expansion corresponding to the rulename // Vector rule_exp; // pick up the rule expansion from the private rule table according to // the input rulename // for (int32 i = 0; i < private_rule_table_d.length(); i++) { JSGFToken t = private_rule_table_d(i).first(); // copy the rule expansion if the rulename is found // if (token_a.term_rule_name_d.eq(t.rulename_d)) { rule_exp = private_rule_table_d(i).second(); for(int32 j = 0; j < rule_exp.length(); j++) { if(token_a.getTokenType() == rule_exp(j).getTokenType() && token_a.terminal_d.eq(rule_exp(j).terminal_d) && rule_exp(j).vertex_index_d == -1) { rule_exp(j).setVertexIndex(vertex_list_index_d); rule_exp(j).setTermRuleName(t.rulename_d); break; } } // create a pair of rule name and rule expansion // Pair< JSGFToken, Vector > pair; pair.assign(t, rule_exp); private_rule_table_d(i).assign(pair); found = true; break; } } // if the rule expansion cannot be found in the private rule table, // search it in the public rule table // if (!found) { for (int32 i = 0; i < public_rule_table_d.length(); i++) { JSGFToken t = public_rule_table_d(i).first(); // copy the rule expansion if the rulename is found // if (token_a.term_rule_name_d.eq(t.rulename_d)) { rule_exp = public_rule_table_d(i).second(); for(int32 j = 0; j < rule_exp.length(); j++) { if(token_a.getTokenType() == rule_exp(j).getTokenType() && token_a.terminal_d.eq(rule_exp(j).terminal_d) && rule_exp(j).vertex_index_d == -1) { rule_exp(j).setVertexIndex(vertex_list_index_d); rule_exp(j).setTermRuleName(t.rulename_d); break; } } // create a pair of rule name and rule expansion // Pair< JSGFToken, Vector > pair; pair.assign(t, rule_exp); public_rule_table_d(i).assign(pair); found = true; break; } } } // end: if (!found) // error if the rule expansion cannot be found in either of the rule tables // if (!found) { String output(L"referred rule <"); output.concat(token_a.term_rule_name_d); output.concat(L"> not found"); return Error::handle(name(), output, Error::TEST, __FILE__, __LINE__); } // gracefully exit // return true; } // method: replaceRecursionRuleReference // // arguments: String& rulename_a: (input) a given rule reference name // Stack replaced_rules_a: (input) replaced rule vector // return: a bool8 value indicating status // // This method takes a JSGF rule expansion and recursively replace all // the rule references with the actual matching rules until only terminal // symbols can be found in the rule expansion without any reference. // bool8 JSGFParser::replaceRecursionRuleReference(String& rulename_a, Stack replaced_rules_a, Queue& rule_final_a) { // store the input rulename in order to be checked for // the potential right recursion // replaced_rules_a.push(&rulename_a); // get the corresponding rule expansion of the input rulename // Vector rule; resolveReference(rulename_a, rule); int32 index = 0; String term_rule_name; term_rule_name.assign(rulename_a); // loop through the rule expansion and replace all rule references // while (index < rule.length()) { JSGFToken current = rule(index); // add all non-rulename token into the class-protected final token queue // if (current.getTokenType() != JSGFToken::RULE_NAME) { rule_final_a.add(¤t); } // else, the token is a rulename suggesting a rule reference // else { // first check if a right recursion is formed with // the current rule reference // bool8 recursion = false; // if the current rule reference forms a right recursion to // a previously processed rule if(replaced_rules_a.contains(¤t.rulename_d)) { // create a marker "@@" token to indicate this right recursion // JSGFToken recur_marker; recur_marker.setMarker(L"@@", current); // add it into the final queue // rule_final_a.add(&recur_marker); // update the bool8 status // recursion = true; } // if no right recursion is found, the current rule reference needs // to be replaced by its corresponding rule expansion // if (!recursion) { // add a "(" left brace for starting a rule extension // JSGFToken left, right; Vector head, tail; for(int32 i = index + 1; i < rule.length(); i++) { tail.concat(rule(i)); } left.setToken(L"("); head.concat(left); index = 0; rule_final_a.add(&left); replaced_rules_a.push(¤t.rulename_d); // get the corresponding rule expansion of the input rulename // Vector rule1; resolveReference(current.rulename_d, rule1); head.concat(rule1); term_rule_name.assign(current.rulename_d); // add a ")" close brace for closing the rule extension // right.setToken(L")"); right.setTermRuleName(current.rulename_d); head.concat(right); rule.clear(); rule.concat(head); rule.concat(tail); } } // end: if (current.getTokenType() != 4) else structure index++; } // end: while(index < rule.length()) // gracefully exit // return true; }