📄 jp_06.cc
字号:
// file: $isip/class/asr/JSGFParser/jp_06.cc// version: $Id: jp_06.cc,v 1.7 2002/07/10 14:49:57 wang Exp $//// isip include files//#include "JSGFParser.h"// method: parseGrammar//// arguments: none//// return: a boolean value indicating status//// This method checks through the class-protected token vector to// validate the input JSGF grammar while saving some usefule data//boolean JSGFParser::parseGrammar() { // declare a current token // JSGFToken curr_tok; // get the number of tokens in the token vector // long num_tok = token_vect_d.length(); // make sure the class-protected token index is zero // token_index_d = 0; // set the first token as the current token // if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing grammar header", Error::TEST, __FILE__, __LINE__); } // the first token in the grammar must be a header token // if (curr_tok.token_type_d == 0) { // move to the next token // token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing grammar name declaration", Error::TEST, __FILE__, __LINE__); } } else { Console::put(L"***unexpected token:"); curr_tok.printToken(); return Error::handle(name(), L"missing self-identifying header at the beginning of the grammar", Error::TEST, __FILE__, __LINE__); } // The current token must be a grammar declaration // if (curr_tok.token_type_d == 2) { // store the grammar name as a class-protected data // grammar_name_d.assign(curr_tok.grammar_name_d); // move to the next // token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing grammar body", Error::TEST, __FILE__, __LINE__); } } else { Console::put(L"***unexpected token:"); curr_tok.printToken(); return Error::handle(name(), L"missing grammar declaration after the header", Error::TEST, __FILE__, __LINE__); } // the current token must be a semi-colon // if (curr_tok.operator_d[0].eq(L";")) { token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing grammar body", Error::TEST, __FILE__, __LINE__); } } else { return Error::handle(name(), L"missing semi-colon in grammar declaration", Error::TEST, __FILE__, __LINE__); } // The current token can be an import grammar declaration // while (curr_tok.token_type_d == 3) { // get import rules // //getImport(curr_tok); // move to the next token // token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing grammar body", Error::TEST, __FILE__, __LINE__); } // the current token must be a semi-colon // if (curr_tok.operator_d[0].eq(L";")) { token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing grammar body", Error::TEST, __FILE__, __LINE__); } } else { return Error::handle(name(), L"missing semi-colon in import grammar declaration", Error::TEST, __FILE__, __LINE__); } } // end: while (curr_tok.token_type_d == 3) // Then starting from the current token, the rule definitions come // so make sure each rule definition is valid // while (token_index_d < num_tok) { parseRuleDefinition(); token_index_d++; } // gracefully exit // return true;}// method: parseRuleDefinition//// arguments: none//// return: a boolean value indicating status//// This method checks if a rule definition is valid//boolean JSGFParser::parseRuleDefinition() { // set grouping and optional grouping match flag as zero // grouping_match_d = 0; op_grouping_match_d = 0; // get the total number of tokens // long num_tok = token_vect_d.length(); // initalize current token // JSGFToken curr_tok = token_vect_d(token_index_d); // The first token can be a public keyword // if (curr_tok.token_type_d == 1) { token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing rule definition", Error::TEST, __FILE__, __LINE__); } } // The current token can be a rule name // if (curr_tok.token_type_d == 4) { token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing rule definition", Error::TEST, __FILE__, __LINE__); } } // error if the current token is neither of the above // else { Console::put(L"***unexpected token:"); curr_tok.printToken(); return Error::handle(name(), L"invalid rule definition", Error::TEST, __FILE__, __LINE__); } // The current token must be operator= // if (curr_tok.operator_d[0].eq(L"=")) { token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing rule exapnsion for rule definition", Error::TEST, __FILE__, __LINE__); } } else { Console::put(L"***unexpected token:"); curr_tok.printToken(); return Error::handle(name(), L"missing operator= in the rule definition", Error::TEST, __FILE__, __LINE__); } // starting from the current token, check if a valid rule expansion exists // if (curr_tok.operator_d[0].ne(L";")) { parseRuleExpansion(); } // semicolon can not follow operator= without rule expansion defined // else { return Error::handle(name(), L"missing rule expansion defined", Error::TEST, __FILE__, __LINE__); } // check grouping flags // if (grouping_match_d != 0) { return Error::handle(name(), L"missing left brace ( in grouping", Error::TEST, __FILE__, __LINE__); } if (op_grouping_match_d != 0) { return Error::handle(name(), L"missing left bracket [ in optional grouping", Error::TEST, __FILE__, __LINE__); } // gracefully exit // return true;}// method: parseRuleExpansion//// arguments: none//// return: a boolean value indicating status//// This method checks if a rule expansion is valid//boolean JSGFParser::parseRuleExpansion() { // get the total number of tokens // long num_tok = token_vect_d.length(); // initalize current token // JSGFToken curr_tok = token_vect_d(token_index_d); while (curr_tok.operator_d[0].ne(L";") && curr_tok.operator_d[0].ne(L")") && curr_tok.operator_d[0].ne(L"]")) { // boolean variable to check if alternative is weighted or not // boolean weighted = false; // the current token can be weight // if (curr_tok.token_type_d == 8) { // update the weighted flag // weighted = true; // move to the next // token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing semi-colon for rule definition", Error::TEST, __FILE__, __LINE__); } } // the current token must lead to a unit // parseUnit(); curr_tok = token_vect_d(token_index_d); // current token can be a vertical bar | indicating alternative // if (curr_tok.operator_d[0].eq(L"|")) { token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing semi-colon for rule definition", Error::TEST, __FILE__, __LINE__); } // semi-colon can not follow vertical bar // if (curr_tok.operator_d[0].eq(L";") || curr_tok.operator_d[0].eq(L")") || curr_tok.operator_d[0].eq(L"]")) { return Error::handle(name(), L"invalid rule component after the vertical bar |", Error::TEST, __FILE__, __LINE__); } // if a weight is specified for one item in a set of alternatives // then a weight must be specified for every item // if a weight token is set for the unit before the vertical bar | // the current token is required to be weight // if ((weighted) && (curr_tok.token_type_d != 8)) { Console::put(L"***unexpected token:"); curr_tok.printToken(); return Error::handle(name(), L"no matching weight token after the vertical bar |", Error::TEST, __FILE__, __LINE__); } // error if a weight token is not set for the unit before // the vertical bar | while the current token is weight token // if ((!weighted) && (curr_tok.token_type_d == 8)) { Console::put(L"***unexpected token:"); curr_tok.printToken(); return Error::handle(name(), L"no matching weight token before the vertical bar |", Error::TEST, __FILE__, __LINE__); } } } // end: while (curr_tok.operator_d[0].ne(L";") && ...) // update grouping match flags // if (curr_tok.operator_d[0].eq(L")")) { grouping_match_d--; } else if (curr_tok.operator_d[0].eq(L"]")) { op_grouping_match_d--; } // gracefully exit // return true;}// method: parseUnit//// arguments: none//// return: a boolean value indicating status//// This method checks if a rule expansion is valid//boolean JSGFParser::parseUnit() { // get the total number of tokens // long num_tok = token_vect_d.length(); // initalize current token // JSGFToken curr_tok = token_vect_d(token_index_d); // the current can be terminal symbol, quoted token or rule reference // if ((curr_tok.token_type_d == 4) || (curr_tok.token_type_d == 5) || (curr_tok.token_type_d == 7)) { // move to the next // token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing semi-colon for rule definition", Error::TEST, __FILE__, __LINE__); } } // the current token can lead to a grouping with () parentheses // else if (curr_tok.operator_d[0].eq(L"(")){ grouping_match_d++; parseGrouping(); curr_tok = token_vect_d(token_index_d); } // the current token can lead to an optional grouping with [] brackets // else if (curr_tok.operator_d[0].eq(L"[")){ op_grouping_match_d++; parseOptionalGrouping(); curr_tok = token_vect_d(token_index_d); } // otherwise invalid // else { Console::put(L"***unexpected token:"); curr_tok.printToken(); return Error::handle(name(), L"invalid use of rule component at this position", Error::TEST, __FILE__, __LINE__); } // the current token can be a unary operator * or + // if (curr_tok.operator_d[0].eq(L"*") || curr_tok.operator_d[0].eq(L"+")) { token_index_d++; if (!(token_index_d < num_tok)) { return Error::handle(name(), L"missing semi-colon for rule definition", Error::TEST, __FILE__, __LINE__); } } // or the current token can also be a tag // else if (curr_tok.token_type_d == 6) { // multiple tags followed are allowed // while (curr_tok.token_type_d == 6) { token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing semi-colon for rule definition", Error::TEST, __FILE__, __LINE__); } } } // gracefully exit // return true;}// method: parseGrouping//// arguments: none//// return: a boolean value indicating status//// This method checks if a rule expansion is valid//boolean JSGFParser::parseGrouping() { // get the total number of tokens // long num_tok = token_vect_d.length(); // declare current token // JSGFToken curr_tok; // move to the next // token_index_d++; curr_tok = token_vect_d(token_index_d); // make sure the current token is not right brace ) // empty grouping () is illegal // if (curr_tok.operator_d[0].eq(L")")) { return Error::handle(name(), L"empty grouping () is illegal", Error::TEST, __FILE__, __LINE__); } // followed can be any valid rule expansion // if (token_index_d < num_tok) { parseRuleExpansion(); } else { return Error::handle(name(), L"invalid using ( left brace", Error::TEST, __FILE__, __LINE__); } // get the current token // curr_tok = token_vect_d(token_index_d); // the current token must be ) right parentheses // if (curr_tok.operator_d[0].eq(L")")) { // move to the next // token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing semi-colon for rule definition", Error::TEST, __FILE__, __LINE__); } } else { Console::put(L"***unexpected token:"); curr_tok.printToken(); return Error::handle(name(), L"missing ) right brace in grouping", Error::TEST, __FILE__, __LINE__); } // gracefully exit // return true;}// method: parseOptionalGrouping//// arguments: none//// return: a boolean value indicating status//// This method checks if a rule expansion is valid//boolean JSGFParser::parseOptionalGrouping() { // get the total number of tokens // long num_tok = token_vect_d.length(); // declare current token // JSGFToken curr_tok; // move to the next // token_index_d++; curr_tok = token_vect_d(token_index_d); // make sure the current token is not right brace ) // empty optional grouping [] is illegal // if (curr_tok.operator_d[0].eq(L"]")) { return Error::handle(name(), L"empty optional grouping [] is illegal", Error::TEST, __FILE__, __LINE__); } // followed can be any valid rule expansion // if (token_index_d < num_tok) { parseRuleExpansion(); } else { return Error::handle(name(), L"invalid using [ left brace", Error::TEST, __FILE__, __LINE__); } // get the current token // curr_tok = token_vect_d(token_index_d); // the current token must be ] right bracket // if (curr_tok.operator_d[0].eq(L"]")) { // move to the next // token_index_d++; if (token_index_d < num_tok) { curr_tok = token_vect_d(token_index_d); } else { return Error::handle(name(), L"missing semi-colon for rule definition", Error::TEST, __FILE__, __LINE__); } } else { Console::put(L"***unexpected token:"); curr_tok.printToken(); return Error::handle(name(), L"missing ] right bracket in optional grouping", Error::TEST, __FILE__, __LINE__); } // gracefully exit // return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -