// file: $isip/class/pr/LanguageModelJSGF/lmjsgf_04.cc // // there is no source code in this file // // isip include files // #include "LanguageModelJSGF.h" // method: write // // arguments: // Sof& sof: (input) sof file object // int32 tag: (input) sof object instance tag // const String& name: (input) sof object instance name // // return: bool8 value indicating status // // this method has the object write itself to an Sof file // bool8 LanguageModelJSGF::write(Sof& sof_a, int32 tag_a, const String& name_a) const { int32 obj_size = 0; // write the instance of the object into the Sof file // if (sof_a.isText()) { // set the size to by dynamic // obj_size = Sof::ANY_SIZE; } else { // the size index and the size of each element // obj_size = sofSize(); } // write the object into the sof file's index // if (!sof_a.put(name_a, tag_a, obj_size)) { return false; } // exit gracefully // return writeData(sof_a); } // method: writeData // // arguments: // Sof& sof: (input) sof file object // const String& pname: (input) parameter name // // return: bool8 value indicating status // // this method has the object write itself to an Sof file. it assumes // that the Sof file is already positioned correctly. // bool8 LanguageModelJSGF::writeData(Sof& sof_a, const String& pname_a) const { // write a start string if necessary // sof_a.writeLabelPrefix(pname_a); HierarchicalDigraph h_digraph(rm_d.second()); Vector temp_vector; // write the start symbol // temp_vector.concat(START_SYMBOL); if (!writeSymbolType(sof_a, DEF_LEVEL, PARAM_JSGF_START_SYMBOL, temp_vector)) { return Error::handle(name(), L"error writing start symbol", Error::WRITE, __FILE__, __LINE__); } temp_vector.clear(); // write the term symbol // temp_vector.concat(TERM_SYMBOL); if (!writeSymbolType(sof_a, DEF_LEVEL, PARAM_JSGF_TERM_SYMBOL, temp_vector)) { return Error::handle(name(), L"error writing term symbol", Error::WRITE, __FILE__, __LINE__); } temp_vector.clear(); // loop over each level // for (int32 level = 0; level < h_digraph.length(); level++) { // write the level tag // temp_vector.concat(h_digraph(level).getLevelTag()); if (!writeSymbolType(sof_a, level, SearchLevel::PARAM_LEVEL_TAG, temp_vector)) { return Error::handle(name(), L"error writing level tag", Error::WRITE, __FILE__, __LINE__); } temp_vector.clear(); // write the grammars for this level // if (!writeGrammars(sof_a, level, h_digraph)) { return Error::handle(name(), L"error writing grammars", Error::WRITE, __FILE__, __LINE__); } // write the nonspeech boundary symbols // writeSymbolType(sof_a, level, SearchLevel::PARAM_NONSPEECH_BOUNDARY_SYMBOL, h_digraph(level).getNonSpeechBoundarySymbolTable()); // write the nonspeech internal symbols // writeSymbolType(sof_a, level, SearchLevel::PARAM_NONSPEECH_INTERNAL_SYMBOL, h_digraph(level).getNonSpeechInternalSymbolTable()); // write the dummy symbols // writeSymbolType(sof_a, level, SearchLevel::PARAM_DUMMY_SYMBOL, h_digraph(level).getDummySymbolTable()); // write the exclude symbols // writeSymbolType(sof_a, level, SearchLevel::PARAM_EXCLUDE_SYMBOL, h_digraph(level).getExcludeSymbolTable()); // write the nsymbol exclude symbols // writeSymbolType(sof_a, level, SearchLevel::PARAM_NSYMBOL_EXCLUDE_SYMBOL, h_digraph(level).getNSymbolExcludeSymbolTable()); // write the spenalty exclude symbols // writeSymbolType(sof_a, level, SearchLevel::PARAM_SPENALTY_EXCLUDE_SYMBOL, h_digraph(level).getSPenaltyExcludeSymbolTable()); // write the context less symbols // writeSymbolType(sof_a, level, SearchLevel::PARAM_CONTEXTLESS_SYMBOL, h_digraph(level).getContextLessSymbolTable()); // write the skip symbols // writeSymbolType(sof_a, level, SearchLevel::PARAM_SKIP_SYMBOL, h_digraph(level).getSkipSymbolTable()); // write the non adaptation symbols // writeSymbolType(sof_a, level, SearchLevel::PARAM_NON_ADAPT_SYMBOL, h_digraph(level).getNonAdaptSymbolTable()); // write the context mapping (if it exists) for this level // if (h_digraph(level).getContextMap().length() > 0) { if (!writeContextMapping(sof_a, level, h_digraph)) { return Error::handle(name(), L"error writing context mapping", Error::WRITE, __FILE__, __LINE__); } } } // put an end string if necessary // sof_a.writeLabelSuffix(pname_a); // exit gracefully // return true; } // method: writeGrammars // // arguments: // Sof& sof: (input) sof file object // int32 leve: the current level // // return: bool8 value indicating status // // this method writes the grammar for a particular level to the // language model file // bool8 LanguageModelJSGF::writeGrammars(Sof& sof_a, int32 level_a, HierarchicalDigraph& h_digraph_a) const { Vector grammars; Vector symbols; String param_name(PARAM_GRAMMARS); param_name.concat(PARAM_UNDERSCORE); param_name.concat((Long)level_a); int32 num_graphs = grammars_d(level_a).length(); // find out if we had context mapping in the previous level. // if so, we need to create a new set of symbols corresponding // to each of the contexts. these symbols will be used to label // the subgraphs for each context. if there is no context in // the previous level, we'll use the regular search symbols // if (level_a > 0) { if (h_digraph_a(level_a - 1).getContextMap().length() > 0) { for (int32 j = 0; j < num_graphs; j++) { String symbol; symbol.assign(CONTEXT_LABEL_PREFIX); Ulong index; index.assign(j); symbol.concat(index); symbols.concat(symbol); } } else { symbols.assign(h_digraph_a(level_a-1).getSymbolTable()); } } // if this is the top level (level 0), the name of the graph is, // by default, TOP_GRAMMAR_NAME else { symbols.concat(TOP_GRAMMAR_NAME); } // loop through all of the graphs, create the grammar string, and // add the grammar string to the grammars vector // for (int i = 0; i < num_graphs; i++) { // declare a JSGF grammar string // // String jsgf_grammar(PARAM_JSGF_VERSION); //jsgf_grammar.concat(L"\n "); String jsgf_grammar; // get the graph // //DiGraph& graph = h_digraph_a(level_a).getSubGraph(i); // convert graph JSGF // // jsgf_grammar.concat(digraphToJSGF(graph, symbols(i))); convertTokensToString(grammars_d(level_a)(i), jsgf_grammar); // add this grammar to the vector of strings // grammars.concat(jsgf_grammar); } return grammars.writeData(sof_a, param_name); } // method: writeSymbolType // // arguments: // Sof& sof: (input) sof file object // // return: a bool8 value indicating status // // this method read one rule from the sof file // bool8 LanguageModelJSGF::writeSymbolType(Sof& sof_a, int32 level_a, const String& pname_a, Vector symbol_list_a) const { // don't write if there are no symbols and we're in // text mode // if (symbol_list_a.length() == 0 && sof_a.isText()) { return false; } // resulting JSGF grammar // String grammar; // parameter name // String param_name(pname_a); // set up the parameter name according to the level index // if (level_a != DEF_LEVEL) { param_name.concat(PARAM_UNDERSCORE); param_name.concat((Long)level_a); } // set up the JSGF grammar for particular symbol type // grammar.assign(L"\n "); grammar.concat(PARAM_JSGF_VERSION); grammar.concat(L"\n "); grammar.concat(COMMENT_GRAMMAR_NAME); grammar.concat(L"\n grammar network.grammar."); // JSGFParser needs to be modified so that this isn't necessary. // without these conditional statements, parser will not read // start and term symbols correctly // String temp_name; if (pname_a.eq(PARAM_JSGF_START_SYMBOL)) { temp_name.assign(START_SYMBOL_REFERENCE); } else if (pname_a.eq(PARAM_JSGF_TERM_SYMBOL)) { temp_name.assign(TERM_SYMBOL_REFERENCE); } else { temp_name.assign(pname_a); } grammar.concat(temp_name); grammar.concat(L";\n\n "); grammar.concat(COMMENT_SYMBOLS); grammar.concat(L"\n public <"); grammar.concat(temp_name); grammar.concat(L"> = "); for (int i = 0 ; i < symbol_list_a.length(); i++) { grammar.concat(symbol_list_a(i)); grammar.concat(L" "); } grammar.concat(L";\n"); // write to the sof file // return grammar.writeData(sof_a, param_name); } // method: writeContextMapping // // arguments: // Sof& sof: (input) sof file object // const int32 tag: (input) sof object instance tag // SearchLevel& level: (input) search level // int32 level_index: (input) search level index // // return: a bool8 value indicating status // // this method has the object store itself from an Sof file according // to the specified name and tag // bool8 LanguageModelJSGF::writeContextMapping(Sof& sof_a, int32 level_a, HierarchicalDigraph& h_digraph_a) const { // local variable // Vector contexts; Vector context_maps; String jsgf_prefix; // parameter name // String param_name(SearchLevel::PARAM_CONTEXT_MAPPING); // set up the parameter name according to the level index // param_name.concat(PARAM_UNDERSCORE); param_name.concat((Long)level_a); // JSGF prefix for the grammar (common to all the contetmaps in JSGF // format) // jsgf_prefix.assign(PARAM_JSGF_VERSION); jsgf_prefix.concat(L"\n "); jsgf_prefix.concat(COMMENT_GRAMMAR_NAME); jsgf_prefix.concat(L"\n grammar network.grammar.context;\n\n "); jsgf_prefix.concat(COMMENT_CONTEXT_RULE); jsgf_prefix.concat(L"\n"); // get the context maps from the searchlevel // contexts.assign(h_digraph_a(level_a).getContextMap()); // set the length of the context-maps // int32 len = contexts.length(); context_maps.setCapacity(len); context_maps.setLength(len); // loop over all the context_maps and parse string in each loop // for (int32 k = 0; k < contexts.length(); k++) { // local variable // String rule_name; String context_map; Vector context; Ulong index; // get the context and the context-index from the current // context-map // context = contexts(k).getContext(); index = contexts(k).getContextIndex(); // set the rule name // rule_name.assign(L" public <"); for (int32 i = 0; i < context.length(); i++){ // read the rule name // rule_name.concat(context(i)); if ( i != (context.length() - 1)){ rule_name.concat(L"-"); } } rule_name.concat(L"> = "); rule_name.concat(CONTEXT_LABEL_PREFIX); rule_name.concat(index); rule_name.concat(L" ;"); context_map.assign(jsgf_prefix); context_map.concat(rule_name); // add this JSGF contextmap to the output vector // context_maps(k).assign(context_map); } // write the vector of contextmaps to the sof file // context_maps.writeData(sof_a, param_name); // exit gracefully // return true; } // method: convertTokensToString // // arguments: // Vector: (input) a list of JSGF tokens // String&: (output) a string containing the JSGF grammar // to be written to a file // // return: a bool8 value indicating status // // // bool8 LanguageModelJSGF::convertTokensToString(Vector grammar_a, String& string_grammar_a) const { String string_grammar; // loop over tokens for this graph and convert them to the // appropriate string. this is a very simple process. // for (int32 i = 0; i < grammar_a.length(); i++) { if (grammar_a(i).getTokenType() == JSGFToken::HEADER) { string_grammar.concat(PARAM_JSGF_VERSION); string_grammar.concat(L"\n"); } else if (grammar_a(i).getTokenType() == JSGFToken::KEYWORD) { string_grammar.concat(grammar_a(i).getKeyword()); string_grammar.concat(L" "); } else if (grammar_a(i).getTokenType() == JSGFToken::GRAMMAR_NAME) { string_grammar.concat(L" "); string_grammar.concat(KEYWORD_GRAMMAR); string_grammar.concat(L" "); string_grammar.concat(grammar_a(i).getGrammarName()); } else if (grammar_a(i).getTokenType() == JSGFToken::IMPORT_GRAMMAR_NAME) { // not yet implemented // } else if (grammar_a(i).getTokenType() == JSGFToken::RULE_NAME) { string_grammar.concat(grammar_a(i).operator_d(OPERATOR_OPEN_POS)); string_grammar.concat(grammar_a(i).getRuleName()); string_grammar.concat(grammar_a(i).operator_d(OPERATOR_CLOSE_POS)); } else if (grammar_a(i).getTokenType() == JSGFToken::TERMINAL) { string_grammar.concat(L" "); if (grammar_a(i).getTerminal().eq(START_SYMBOL)) { string_grammar.concat(OPERATOR_OPENANGLEBRACKET); string_grammar.concat(PARAM_JSGF_START_SYMBOL); string_grammar.concat(OPERATOR_CLOSEANGLEBRACKET); } else if (grammar_a(i).getTerminal().eq(TERM_SYMBOL)) { string_grammar.concat(PARAM_JSGF_TERM_SYMBOL); } else { string_grammar.concat(grammar_a(i).getTerminal()); } } else if (grammar_a(i).getTokenType() == JSGFToken::TAG) { // not yet implemented // } else if (grammar_a(i).getTokenType() == JSGFToken::QUOTED_TOKEN) { // not yet implemented // } else if (grammar_a(i).getTokenType() == JSGFToken::WEIGHT) { string_grammar.concat(L" "); string_grammar.concat(grammar_a(i).operator_d(OPERATOR_OPEN_POS)); string_grammar.concat(grammar_a(i).getWeight()); string_grammar.concat(grammar_a(i).operator_d(OPERATOR_CLOSE_POS)); } else if (grammar_a(i).getTokenType() == JSGFToken::OPERATOR) { if (grammar_a(i).operator_d(OPERATOR_OPEN_POS).eq(L";")) { string_grammar.concat(grammar_a(i).operator_d(OPERATOR_OPEN_POS)); string_grammar.concat(L"\n"); } else { string_grammar.concat(L" "); string_grammar.concat(grammar_a(i).operator_d(OPERATOR_OPEN_POS)); } } else if (grammar_a(i).getTokenType() == JSGFToken::MARKER) { // not yet implemented // } } string_grammar_a.assign(string_grammar); // exit gracefully // return true; }