⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vxirec_utils.cpp

📁 openvxi3.4是一个voicexml对话脚本语言的解释器源码.可用VC6.0编译.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
void VXIrecData::ShowPropertyValue(const VXIchar *key,
           const VXIValue *value, VXIunsigned PROP_TAG)
{
  VXIchar subtag[512] = L"Property";
  if( value == 0 ) return;
  VXIvalueType type = VXIValueGetType(value);
  {
    switch( type )
    {
      case VALUE_INTEGER:
        wcscpy(subtag, L"Property:INT");
        LogDiag(PROP_TAG, subtag, 
             L"%s=%d", key, VXIIntegerValue((const VXIInteger*)value));
        break;
      case VALUE_FLOAT:
        wcscpy(subtag, L"Property:FLT");
        LogDiag(PROP_TAG, subtag, 
             L"%s=%f", key, VXIFloatValue((const VXIFloat*)value));
        break;
      case VALUE_BOOLEAN:     
        wcscpy(subtag, L"Property:BOOL");
        LogDiag(PROP_TAG, subtag, 
             L"%s=%d", key, VXIBooleanValue((const VXIBoolean*)value));
        break;
      case VALUE_STRING:
        wcscpy(subtag, L"Property:STR");
        LogDiag(PROP_TAG, subtag, 
             L"%s=%s", key, VXIStringCStr((const VXIString*)value));
        break;
      case VALUE_PTR:
        wcscpy(subtag, L"Property:PTR");
        LogDiag(PROP_TAG, subtag, 
             L"%s(ptr)=0x%p", key, VXIPtrValue((const VXIPtr*)value));
        break;
      case VALUE_CONTENT:
        wcscpy(subtag, L"Property:CNT");
        LogDiag(PROP_TAG, subtag, 
             L"%s(content)=0x%p", key, value);
        break;
      case VALUE_MAP:
        {
          VXIchar endtag[512];
          const VXIchar *mykey = key ? key : L"NULL";
          wcscpy(subtag, L"Property:MAP:BEG");
          wcscpy(endtag, L"Property:MAP:END");
          LogDiag(PROP_TAG, subtag, L"%s", mykey);
          const VXIchar *key = NULL;
          const VXIValue *gvalue = NULL;

          VXIMapIterator *it = VXIMapGetFirstProperty((const VXIMap*)value, &key, &gvalue);
          int ret = 0;
          while( ret == 0 && key && gvalue )
          {
            ShowPropertyValue(key, gvalue, PROP_TAG);
            ret = VXIMapGetNextProperty(it, &key, &gvalue);
          }
          VXIMapIteratorDestroy(&it);         
          LogDiag(PROP_TAG, endtag, L"%s", mykey);
        }   
        break;
      case VALUE_VECTOR:
        {
          VXIunsigned vlen = VXIVectorLength((const VXIVector*)value);
          for(VXIunsigned i = 0; i < vlen; ++i)
          {
            const VXIValue *gvalue = VXIVectorGetElement((const VXIVector*)value, i);
            ShowPropertyValue(L"Vector", gvalue, PROP_TAG);
          }
        }
        break;
      default:
        LogDiag(PROP_TAG, subtag, L"%s=%s", key, L"UNKOWN");
    }          
  }
  return;
}

void VXIrecData::ShowPropertyValue(const VXIMap *properties)
{
  const VXIchar *key = NULL;
  const VXIValue *gvalue = NULL;
  const VXIunsigned PROP_TAG = DIAG_TAG_PROPERTY;
  if( log && (log->DiagnosticIsEnabled(log, diagLogBase+PROP_TAG) == TRUE) 
      && properties ) 
  {
    VXIMapIterator *it = VXIMapGetFirstProperty(properties, &key, &gvalue);
    int ret = 0;
    while( ret == 0 && key && gvalue )
    {
      ShowPropertyValue(key, gvalue, PROP_TAG);
      ret = VXIMapGetNextProperty(it, &key, &gvalue);
    }
    VXIMapIteratorDestroy(&it);     
  }
  return;
}

// Pasre SRGS grammar
// NOTES: re-parse the same grammar seems to be slow, optimization is welcome!
//
VXIrecGrammar * VXIrecData::ParseSRGSGrammar(const vxistring & srgsgram, 
                                             const VXIMap    * properties,
                                             bool isdtmf)
{
  const VXIchar* fnname = L"ParseSRGSGrammar";
  LogBlock logger(log, VXIrecData::diagLogBase, fnname, VXIREC_MODULE);

  VXIrecWordList * newGrammarPtr = new VXIrecWordList();
  
  try {
    xmlHandler->CreateGrammarInfoList();
    const VXIbyte* buffer = reinterpret_cast<const VXIbyte*>(srgsgram.c_str());
    VXIulong bufSize = srgsgram.length() * sizeof(VXIchar) / sizeof(VXIbyte);
    MemBufInputSource membuf(buffer, bufSize, "SRGSGRAM", false);
    parser->parse(membuf);
  }
  catch (const XMLException & exception) {
    LogError(352, L"%s%s", L"Parse Error", XMLChToVXIchar(exception.getMessage()).c_str());
    xmlHandler->DestroyGrammarInfoList();
    delete newGrammarPtr;
    return NULL;
  }
  catch (const SAXParseException & exception) {
    LogError(353, L"%s%s%s%d%s%d%s%s",
             L"ID", XMLChToVXIchar(exception.getSystemId()).c_str(),
             L"line", exception.getLineNumber(),
             L"col", exception.getColumnNumber(),
             L"msg", XMLChToVXIchar(exception.getMessage()).c_str());
    xmlHandler->DestroyGrammarInfoList();
    delete newGrammarPtr;
    return NULL;
  }

  // Take the ownership of grammar info list
  if( !isdtmf ) isdtmf = xmlHandler->isDTMFGrammar();
  newGrammarPtr->gtype = ( isdtmf ? VXIrecWordList::GTYPE_DTMF : 
                           VXIrecWordList::GTYPE_SPEECH);
  newGrammarPtr->grammarInfoList = xmlHandler->AcquireGrammarInfoList();
  return newGrammarPtr;
}

void VXIrecData::Clear()
{
  if( !grammars.empty() )
    for (GRAMMARS::iterator i = grammars.begin(); i != grammars.end(); ++i)
      delete *i;
  grammars.clear();
}

void VXIrecData::ActivateGrammar(VXIrecGrammar *g)
{
  g->SetEnabled(true);
  activeGrammars.push_back(g);
}

void VXIrecData::DeactivateGrammar(VXIrecGrammar *g)
{
  g->SetEnabled(false);
  activeGrammars.remove(g);
}

int VXIrecData::GetActiveCount() const
{
  /*int count = 0;
  for (GRAMMARS::const_iterator i = grammars.begin(); i != grammars.end(); ++i) {
    if ((*i)->IsEnabled()) count++;
  }
  return count;*/
  return activeGrammars.size();
}

void VXIrecData::AddGrammar(VXIrecGrammar * l)
{
  if (l == NULL) return;
  grammars.push_front(l);
}


void VXIrecData::FreeGrammar(VXIrecGrammar * l)
{
  if (l == NULL) return;
  if( !grammars.empty() )
    grammars.remove(l);
  delete l;
}


bool VXIrecData::ProcessSemanticInterp(vxistring & result, const VXIrecGrammarInfo *ginfo)
{
  const VXIchar* fnname = L"ProcessSemanticInterp";
  LogBlock logger(log, VXIrecData::diagLogBase, fnname, VXIREC_MODULE);

  result = L"";
  if( !ginfo ) return false;
  if( ginfo->tag.empty() ) {
    // there is no tag
    result = L"<instance></instance>";
    return true;
  }

  // Processin <tag>
  // this is only a partial impl.
  // given a tag of:
  //    x=new Object(); x.a='valueA'; x.b='valueB'; y='valueY'; z='valueZ'; 
  // the following should be created:
  //    <instance>
  //       <x>
  //          <a>valueA</a>
  //          <b>valueB</b>
  //       </x>
  //       <y>valueY</y>
  //       <z>valueZ</z>
  //    </instance>
  //
  // but... this code won't do that.
  vxistring temp = ginfo->tag;
  vxistring::size_type pos = temp.find(L"=");

  // handle simple result.  ex.: <tag>frog</tag> would
  // return <instance>frog</instance>
  if( pos == vxistring::npos ){
    result = L"<instance>" + ginfo->tag + L"</instance>";
    return true;
  }

  result =  L"<instance>";

  bool gotit = false;
  while (!temp.empty() && pos != vxistring::npos ) {
    // retrieve var.
    vxistring semvar = temp.substr(0, pos);
    PruneWhitespace(semvar);

    temp.erase(0, pos+1);
    PruneWhitespace(temp);
   
    // find value
    vxistring value;
    pos = temp.find(L";");
    if( pos == vxistring::npos ) {
      if( temp.empty() ) return false;
      value = temp;
      temp = L"";
    }
    else {
      value = temp.substr(0, pos);
      temp.erase(0, pos+1);
    }

    if( !value.empty() ) {
      PruneWhitespace(value);
      // remove single or double quotes
      if( value[0] == L'\"' ) value.erase(0,1);
      if( value[value.length()-1] == L'\"' ) value.erase(value.length()-1);
      if( value[0] == L'\'' ) value.erase(0,1);
      if( value[value.length()-1] == L'\'' ) value.erase(value.length()-1);
    }
    else {
      result = L"";
      return false;
    }

    // construct semantic
    logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%s%s%s%s%s", L"tag: ", semvar.c_str(),
               L", value: ", value.c_str(),
               L", semantic: ", ginfo->semantic.c_str());
               
    if( semvar == ginfo->semantic ) {
      if( gotit ) {
        result = L"";
        return false;
      }
      gotit = true;
      result += value;
    }
    else {
      result += L"<" + semvar;
      result += L" confidence='100'>";
      result += value;
      result += L"</" + semvar + L">";
    }

    // Search for next var.
    pos = temp.find(L"=");
  }

  result +=  L"</instance>";
  return true;
}

bool VXIrecData::ConstructNLSMLForInput(const VXIchar* input, vxistring & nlsmlresult)
{
  const VXIchar* fnname = L"ConstructNLSMLForInput";
  LogBlock logger(log, VXIrecData::diagLogBase, fnname, VXIREC_MODULE);

  VXIrecGrammar * match = NULL;
  VXIrecGrammarInfo * gInfo = NULL;
  VXIchar gramid[64];
  nlsmlresult = L"";

  if( !input || input[0] == L'\0' ) return false;
  for (GRAMMARS::iterator i = activeGrammars.begin(); i != activeGrammars.end(); ++i) {
    if ((*i)->IsEnabled() && (*i)->GetGrammarInfo(input, &gInfo)) {

      logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%p%s%s",
           (match ? L"Multiple grammars matched " : L"Found matched grammar "),
           (*i), L" for ", gInfo->word.c_str());

      match = *i;

      // Constructing NLSML result
      if( nlsmlresult.empty() ) {
        // header
        nlsmlresult = L"<?xml version='1.0'?>"
                      L"<result>";
      }

      // Create grammar ID
      SWIswprintf(gramid, 64, L"%p", match);

      // interpretation
      nlsmlresult += L"<interpretation grammar='";
      nlsmlresult += gramid;
      nlsmlresult += L"' confidence='99'><input mode='";
      nlsmlresult += ( match->IsDtmf() ? L"dtmf'>" : L"speech'>");
      nlsmlresult += gInfo->word;
      nlsmlresult += L"</input>";

      // Semantic interp.
      vxistring temp(L"");
      if( !ProcessSemanticInterp(temp, gInfo) )
      {
        nlsmlresult = L"";
        break;
      }

      nlsmlresult += temp.c_str();

      // close interpretation
      nlsmlresult += L"</interpretation>";
    }
  }

  if( !nlsmlresult.empty() ) {
    nlsmlresult += L"</result>";
    return true;
  }
  return false;
}


//////////////////////////////////////////////////////
// These routines process JSGF-lite grammars.       //
//////////////////////////////////////////////////////

static const int FINISH_STAGE = 3;
void VXIrecData::ConvertJSGFType(const vxistring & dataIn, JSGFInfo & info)
{
  // search tokens
  const vxistring fEqualToken(L"=");
  const vxistring fCommaToken(L";");
  const vxistring fHeaderToken(L"#JSG");
  vxistring data(dataIn);
  vxistring fVersion;
  vxistring fName;
  vxistring fPublic;

  // search
  vxistring::size_type pos = data.find(fCommaToken);
  int stage = 0;
  while( pos != vxistring::npos && stage < FINISH_STAGE) {
    vxistring temp = data.substr(0, pos);
    switch( stage++ ) {
      case 0: // version
        // confirm JSGF header
        if( temp.find(fHeaderToken) == vxistring::npos) {
          // quit parsing,
          stage = FINISH_STAGE;
          break;
        }
        info.versionStr = temp;
        data.erase(0, pos+1);
        break;
      case 1: // grammar name
        info.nameStr = temp;
        data.erase(0, pos+1);
        break;
      case 2: // public type
      {
        // remove the found token
        data.erase(pos);
        // search for "=" token
        vxistring::size_type tpos = data.find(fEqualToken);
        if( tpos != vxistring::npos ) {
          info.publicStr = data.substr(0, tpos);
          // remove the public string
          data.erase(0, tpos+1);
        }
      } break;
    }
    // Continue searching
    if( stage != FINISH_STAGE ) pos = data.find(fCommaToken);
  }
  // finally copy the content string
  info.contentStr = data;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -