14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------*
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  SemanticProcessorImpl.c                                                  *
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Copyright 2007, 2008 Nuance Communciations, Inc.                         *
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the 'License');          *
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  you may not use this file except in compliance with the License.         *
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  You may obtain a copy of the License at                                  *
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0                           *
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software      *
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  distributed under the License is distributed on an 'AS IS' BASIS,        *
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  See the License for the specific language governing permissions and      *
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  limitations under the License.                                           *
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "SR_SemanticProcessor.h"
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "SR_SemanticProcessorImpl.h"
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "SR_SemanticGraphImpl.h"
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "SR_SemanticResultImpl.h"
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "ESR_ReturnCode.h"
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "plog.h"
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const char* MTAG = __FILE__;
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/**************************************************
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Internal data structures and functions
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ************************************************/
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/**
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * A partial path holds olables from a start arc, until it reaches a
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * fork (i.e. multiple next arc possiblities). For each possibility
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * a new partial path is created and concatenated to this one.
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef struct sem_partial_path_t
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  struct sem_partial_path_t* next; /* linked list */
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arc_token* arc_for_pp;           /* which arc was taken */
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectsem_partial_path;
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define DEBUG_CPF 0
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic arc_token* debug_base_arc_token = 0;
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int debug_depth = 0;
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const char* spaces(int n) {
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const char* sp = "                                                         ";
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int nsp = strlen(sp);
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (n > nsp) n = nsp;
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return sp + nsp - n;
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/**
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * A holder for accumulated scripts
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef struct script_t
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const LCHAR* expression;
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const LCHAR* ruleName;
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectscript;
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/**
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * A list of accumulated scripts
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef struct script_list_t
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  script list[MAX_SCRIPTS];
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t num_scripts;
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectscript_list;
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const LCHAR* WORD_NOT_FOUND = L("word_not_found");
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/**
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Initialize the list of partial paths
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode sem_partial_path_list_init(sem_partial_path* heap, int nheap);
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic sem_partial_path* sem_partial_path_create(sem_partial_path* heap);
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode sem_partial_path_free(sem_partial_path* heap, sem_partial_path* path);
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic void sem_partial_path_print(sem_partial_path* path, sem_partial_path* paths, int npaths, wordmap* ilabels);
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/**
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Look up the word string given the id
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const LCHAR* lookUpWord(SR_SemanticGraphImpl* semgraph, wordID wdid);
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/**
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Look up the actual script string given the label
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const LCHAR* lookUpScript(SR_SemanticGraphImpl* semgraph, const LCHAR* script_label);
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/**
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Recursively accumulate the scripts
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode accumulate_scripts(SR_SemanticGraphImpl* semgraph, script_list* scripts, sem_partial_path* path_root);
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode interpretScripts(SR_SemanticProcessorImpl* semproc, LCHAR* scripts, SR_SemanticResult** result);
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode SR_SemanticProcessorCreate(SR_SemanticProcessor** self)
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SR_SemanticProcessorImpl* impl;
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ESR_ReturnCode rc;
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (self == NULL)
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        PLogError(L("ESR_INVALID_ARGUMENT"));
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return ESR_INVALID_ARGUMENT;
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl = NEW(SR_SemanticProcessorImpl, MTAG);
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (impl == NULL)
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        PLogError(L("ESR_OUT_OF_MEMORY"));
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return ESR_OUT_OF_MEMORY;
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if ((rc = LA_Init(&impl->analyzer)) != ESR_SUCCESS)
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        goto CLEANUP;
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if ((rc = EP_Init(&impl->parser)) != ESR_SUCCESS)
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        goto CLEANUP;
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if ((rc = ST_Init(&impl->symtable)) != ESR_SUCCESS)
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        goto CLEANUP;
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if ((rc = EE_Init(&impl->eval)) != ESR_SUCCESS)
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        goto CLEANUP;
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl->acc_scripts = MALLOC(sizeof(LCHAR) * MAX_SCRIPT_LEN, NULL);
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (impl->acc_scripts == NULL)
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rc = ESR_OUT_OF_MEMORY;
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        PLogError(ESR_rc2str(rc));
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        goto CLEANUP;
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl->Interface.destroy = &SR_SemanticProcessor_Destroy;
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl->Interface.checkParse = &SR_SemanticProcessor_CheckParse;
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl->Interface.checkParseByWordID = &SR_SemanticProcessor_CheckParseByWordID;
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl->Interface.setParam = &SR_SemanticProcessor_SetParam;
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl->Interface.flush = &SR_SemanticProcessor_Flush;
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    *self = (SR_SemanticProcessor*) impl;
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_SUCCESS;
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl->Interface.destroy(&impl->Interface);
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return rc;
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode SR_SemanticProcessor_Destroy(SR_SemanticProcessor* self)
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SR_SemanticProcessorImpl* impl = (SR_SemanticProcessorImpl*) self;
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (self == NULL)
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        PLogError(L("ESR_INVALID_ARGUMENT"));
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return ESR_INVALID_ARGUMENT;
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LA_Free(impl->analyzer);
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    EP_Free(impl->parser);
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ST_Free(impl->symtable);
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    EE_Free(impl->eval);
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (impl->acc_scripts != NULL)
1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        FREE(impl->acc_scripts);
1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        impl->acc_scripts = NULL;
1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    FREE(impl);
1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_SUCCESS;
1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode append_with_check(LCHAR** dst, const LCHAR src, const LCHAR* end)
1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (*dst < end)
1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        **dst = src;
1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        ++(*dst);
1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return ESR_SUCCESS;
1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    PLogError(L("ESR_BUFFER_OVERFLOW"));
1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_BUFFER_OVERFLOW;
1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const LCHAR* LSTRNCHR2(const LCHAR* text, LCHAR c, LCHAR c2, size_t len)
1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (; *text != c && *text != c2 && len > 0 && *text; text++, len--)
1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        ;
1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (len) return text;
1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else return NULL;
1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic size_t get_next_token_len(const char* expr)
1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const char *p;
2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (IS_OPERATOR(expr))
2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return 1;
2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (*expr == ';')
2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return 1;
2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (*expr == '\'')
2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /* a literal */
2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        for (p = expr; *p != '\0'; p++)
2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (*p == '\\' && *(p + 1) == '\'')
2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                ++p;
2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                continue;
2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (p > expr && *p == '\'')
2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                ++p;
2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                break;
2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return p -expr;
2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else
2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        for (p = expr; *p != '\0'; p++)
2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (*p == '(')
2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                ++p;
2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                break;
2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else if (IS_OPERATOR(p) || *p == ';')
2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                break;
2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return p -expr;
2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define firstWord(transcription) transcription
2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define nextWord(transcription)  (transcription && *transcription ? &transcription[LSTRLEN(transcription)+1] : transcription)
2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* assumption is that transcription has been prepared (word split by NULL,
2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project   transcription ends with double NULL */
2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode checkpath_forwardByWordID(SR_SemanticGraphImpl* semgraph,
2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        sem_partial_path* heap,
2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        arc_token* atoken_start,
2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        sem_partial_path *pp,
2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        const wordID* wordIDs)
2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arc_token* atok_use;
2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sem_partial_path* pp_branch;
2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arc_token* atok;
2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const wordID* currentWord = wordIDs;
2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /*****************
2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     * Recursive Part (operate on the next arc or the branch)
2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     *****************/
2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (atok = atoken_start; atok; atok = ARC_TOKEN_PTR(semgraph->arc_token_list, atok->next_token_index))
2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf("%strying arc %d %p ilabel%d(%s) olabel %d\n", spaces(debug_depth), atok-debug_base_arc_token, atok,
2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project               atok->ilabel, atok->ilabel!=MAXwordID?semgraph->ilabels->words[atok->ilabel]:"max",   atok->olabel);
2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        atok_use = NULL;
2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        currentWord = wordIDs;
2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (atok->ilabel < semgraph->ilabels->num_slots && atok->ilabel != WORD_EPSILON_LABEL &&
2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                wordmap_whether_in_rule(semgraph->ilabels, *currentWord, atok->ilabel))
2754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
2764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            /* atok->ilabel is the slotid */
2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            atok_use = arc_tokens_find_ilabel(semgraph->arc_token_list, semgraph->arcs_for_slot[atok->ilabel], *currentWord);
2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (!atok_use)
2794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                arc_token* a;
2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                PLogError(L("ESR_INVALID_STATE: finding wdid %d in slot %d"), *currentWord, atok->ilabel);
2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                for (a = semgraph->arcs_for_slot[atok->ilabel]; 0 && a; a = ARC_TOKEN_PTR(semgraph->arc_token_list, a->next_token_index))
2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    PLogError(L("a %x ilabel %d olabel %d"), a, a->ilabel, a->olabel);
2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
2864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                return ESR_INVALID_STATE;
2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else
2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                ++currentWord;
2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
2914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else if (*currentWord != MAXwordID && atok->ilabel == *currentWord)
2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            ++currentWord;
2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            atok_use = atok;
2954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else if (atok->ilabel == WORD_EPSILON_LABEL) /* more eps transitions */
2974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            atok_use = atok;
2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (atok_use == NULL)
3004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            continue;
3014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else {
3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc_token* atokfna = ARC_TOKEN_PTR(semgraph->arc_token_list, atok->first_next_arc);
3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            pp_branch = sem_partial_path_create(heap);
3044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            printf("%smatched arc %d %p ilabel%d(%s) olabel %d\n", spaces(debug_depth), atok-debug_base_arc_token, atok,
3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                   atok->ilabel, semgraph->ilabels->words[atok->ilabel],   atok->olabel);
3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (!pp_branch)
3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                return ESR_INVALID_STATE;
3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            pp->next = pp_branch;
3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            pp->arc_for_pp = atok_use;
3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (atok->first_next_arc == ARC_TOKEN_NULL && *currentWord == MAXwordID)
3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                return ESR_SUCCESS;
3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else if (atokfna && atokfna->ilabel==MAXwordID && atokfna->olabel==MAXwordID && *currentWord==MAXwordID)
3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                return ESR_SUCCESS;
3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else
3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                sem_partial_path_print(pp_branch, &sem_partial_paths[0], MAX_SEM_PARTIAL_PATHS, semgraph->ilabels);
3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                debug_depth += 2;
3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
3254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                ESR_ReturnCode rc = checkpath_forwardByWordID(semgraph, heap, atokfna, pp_branch, currentWord);
3264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                debug_depth -= 2;
3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (rc == ESR_SUCCESS)
3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    return ESR_SUCCESS;
3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                else if (rc == ESR_INVALID_STATE)
3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /* if out-of-memory of other problem, then just abort */
3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    return ESR_INVALID_STATE;
3354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                else
3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /* need to uncharge through epsilons, until pp->next==pp_branch */
3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    // sem_partial_path* qq = pp->next;
3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    sem_partial_path_free(heap, pp->next);
3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    pp->arc_for_pp = NULL;
3424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    // for (qq = pp->next; qq != pp_branch; qq = qq->next)  sem_partial_path_free(qq);
3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    pp->next = NULL;
3444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf("%sdone trying arc %d %p ilabel%d(%s) olabel %d\n", spaces(debug_depth), atok-debug_base_arc_token, atok,
3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project               atok->ilabel, semgraph->ilabels->words[atok->ilabel],   atok->olabel);
3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    } /* end for atok .. */
3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_NO_MATCH_ERROR;
3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode checkpath_forward(SR_SemanticGraphImpl* semgraph,
3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        sem_partial_path* heap,
3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        arc_token* atoken_start,
3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        sem_partial_path *pp,
3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        const LCHAR* transcription)
3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arc_token* atok_use;
3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    wordID wdID;
3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sem_partial_path* pp_branch;
3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arc_token* atok;
3664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const LCHAR* transp;
3674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /*****************/
3694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* Recursive Part (operate on the next arc or the branch)*/
3704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /*****************/
3714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (atok = atoken_start; atok; atok = ARC_TOKEN_PTR(semgraph->arc_token_list, atok->next_token_index))
3724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
3734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
3744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf("%strying arc %d %p ilabel%d(%s) olabel %d\n", spaces(debug_depth), atok-debug_base_arc_token, atok,
3754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project               atok->ilabel, atok->ilabel!=MAXwordID?semgraph->ilabels->words[atok->ilabel]:"max",   atok->olabel);
3764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
3774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        atok_use = NULL;
3794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        transp = transcription;
3804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        wdID = wordmap_find_index(semgraph->ilabels, firstWord(transp));
3814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (atok->ilabel < semgraph->ilabels->num_slots && atok->ilabel != WORD_EPSILON_LABEL &&
3834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                wordmap_whether_in_rule(semgraph->ilabels, wdID, atok->ilabel))
3844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
3854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            /* atok->ilabel is the slotid */
3864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            atok_use = arc_tokens_find_ilabel(semgraph->arc_token_list, semgraph->arcs_for_slot[atok->ilabel], wdID);
3874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (!atok_use)
3884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
3894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                arc_token* a;
3904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                PLogError(L("ESR_INVALID_STATE: finding wdid %d in slot %d"), wdID, atok->ilabel);
3914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                for (a = semgraph->arcs_for_slot[atok->ilabel]; 0 && a; a = ARC_TOKEN_PTR(semgraph->arc_token_list, a->next_token_index))
3924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
3934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    PLogError(L("a %x ilabel %d olabel %d"), a, a->ilabel, a->olabel);
3944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
3954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                return ESR_INVALID_STATE;
3964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
3974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else {
3984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                transp = nextWord(transp);
3994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                wdID = wordmap_find_index(semgraph->ilabels, firstWord(transp));
4004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
4014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
4024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else if (wdID != MAXwordID && atok->ilabel == wdID)
4034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
4044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            transp = nextWord(transp);
4054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            wdID = wordmap_find_index(semgraph->ilabels, firstWord(transp));
4064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            atok_use = atok;
4074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
4084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else if (atok->ilabel == WORD_EPSILON_LABEL) /* more eps transitions */
4094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            atok_use = atok;
4104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (atok_use == NULL)
4124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            continue;
4134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else {
4144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc_token* atokfna = ARC_TOKEN_PTR(semgraph->arc_token_list, atok->first_next_arc);
4154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            pp_branch = sem_partial_path_create(heap);
4164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
4184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            printf("%smatched arc %d %p ilabel%d(%s) olabel %d\n", spaces(debug_depth), atok-debug_base_arc_token, atok,
4194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                   atok->ilabel, semgraph->ilabels->words[atok->ilabel],   atok->olabel);
4204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
4214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (!pp_branch)
4234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                return ESR_INVALID_STATE;
4244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            pp->next = pp_branch;
4254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            pp->arc_for_pp = atok_use;
4264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (atok->first_next_arc==ARC_TOKEN_NULL && *transp==0)
4274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                return ESR_SUCCESS;
4284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else if (atokfna && atokfna->ilabel==MAXwordID && atokfna->olabel==MAXwordID && *transp==0)
4294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                return ESR_SUCCESS;
4304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else
4314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
4324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
4334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                sem_partial_path_print(pp_branch, &sem_partial_paths[0], MAX_SEM_PARTIAL_PATHS, semgraph->ilabels);
4344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                debug_depth += 2;
4354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
4364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                ESR_ReturnCode rc = checkpath_forward(semgraph, heap, atokfna, pp_branch, transp);
4374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
4384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                debug_depth -= 2;
4394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
4404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (rc == ESR_SUCCESS)
4414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    return rc;
4424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                else if (rc == ESR_INVALID_STATE)
4434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
4444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /* if out-of-memory of other problem, then just abort */
4454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    return ESR_INVALID_STATE;
4464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
4474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                else
4484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
4494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /* need to uncharge through epsilons, until pp->next==pp_branch */
4504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    // sem_partial_path* qq = pp->next;
4514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    sem_partial_path_free(heap, pp->next);
4524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    pp->arc_for_pp = NULL;
4534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    // for (qq = pp->next; qq != pp_branch; qq = qq->next)  sem_partial_path_free(qq);
4544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    pp->next = NULL;
4554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
4564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
4574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
4584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
4594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf("%sdone trying arc %d %p ilabel%d(%s) olabel %d\n", spaces(debug_depth), atok-debug_base_arc_token, atok,
4604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project               atok->ilabel, semgraph->ilabels->words[atok->ilabel],   atok->olabel);
4614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
4624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    } /* end for atok .. */
4634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_NO_MATCH_ERROR;
4644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/**
4674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Parse the graph
4684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
4694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode SR_SemanticProcessor_CheckParseByWordID(SR_SemanticProcessor* self,
4704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                                       SR_SemanticGraph* graph,
4714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                                       wordID* wordIDs,
4724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                                       SR_SemanticResult** results,
4734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                                       size_t* resultCount)
4744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sem_partial_path *path_root;
4764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    script_list raw_scripts_buf;
4774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LCHAR lhs[MAX_STRING_LEN];
4784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LCHAR meaning[MAX_STRING_LEN];      /* special key */
4794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LCHAR ruleName[32];
4804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    size_t i, j, size, resultIdx;
4814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LCHAR* dst = NULL;
4824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LCHAR* p;
4834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    size_t tokenLen = 0;
4844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const LCHAR* src;
4854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    HashMap* hashmap = NULL;
4864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ESR_ReturnCode rc;
4874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ESR_BOOL containsKey;
4884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sem_partial_path heap[MAX_SEM_PARTIAL_PATHS];
4894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SR_SemanticProcessorImpl* semproc  = (SR_SemanticProcessorImpl*) self;
4904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SR_SemanticGraphImpl* semgraph = (SR_SemanticGraphImpl*) graph;
4914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LSTRCPY(ruleName, L(""));
4934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    CHKLOG(rc, sem_partial_path_list_init(heap, sizeof(heap)/sizeof(heap[0])));
4944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    path_root = sem_partial_path_create(heap);
4954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!path_root)
4964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
4974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rc = ESR_INVALID_STATE;
4984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        goto CLEANUP;
4994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
5004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /**
5024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     * Parse the graph
5034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     */
5044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    rc = checkpath_forwardByWordID(semgraph, heap, &semgraph->arc_token_list[0], path_root,
5054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                   wordIDs);
5064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (rc == ESR_NO_MATCH_ERROR)
5074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
5084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        *resultCount = 0;
5094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return ESR_SUCCESS; /* did not parse */
5104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
5114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (rc == ESR_SUCCESS)
5124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
5134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (*resultCount > 0)
5144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            *resultCount = 1;
5154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else
5164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
5174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            /**
5184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             * If the array to hold the results is not big enough,
5194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             * then tell the user right away by returning ESR_BUFFER_OVERFLOW
5204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       with the size required returned in resultCount */
5214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            rc = ESR_BUFFER_OVERFLOW;
5224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            PLogError(ESR_rc2str(rc));
5234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            goto CLEANUP;
5244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
5254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
5264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (rc == ESR_INVALID_STATE)
5274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        goto CLEANUP;
5284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
5304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sem_partial_path_print(path_root, &sem_partial_paths[0], MAX_SEM_PARTIAL_PATHS,semgraph->ilabels);
5314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
5324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* create the array of Semantic Result Pointers */
5344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (resultIdx = 0; resultIdx < *resultCount; resultIdx++)
5354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
5364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        raw_scripts_buf.num_scripts = 0;
5374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        for (i = 0; i < MAX_SCRIPTS; i++)
5384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
5394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            raw_scripts_buf.list[i].expression = 0;
5404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            raw_scripts_buf.list[i].ruleName = 0;
5414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
5424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /*
5444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * Go through the partial paths which were successful and accumulate the scripts
5454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * that you encountered (BUGGY)
5464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         */
5474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, accumulate_scripts(semgraph, &raw_scripts_buf, path_root));
5484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, sem_partial_path_free(heap, path_root));
5494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /*pfprintf(PSTDOUT,"Accumulated scripts\n");*/
5514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /*
5534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * Prepare the scripts for processing, in other words, make them "nice".
5544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * What I mean by making them nice is to do stuff like:
5554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *
5564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * if ruleName is:   root}
5574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *    expression is: meaning='hello';meaning=meaning+' '+'world';
5584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *
5594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * what I want to accumulate is
5604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *    root.meaning='hello';root.meaning=root.meaning+' '+'world';
5614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *
5624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * I am basically replacing END_SCOPE_MARKER with '.'  and inserting 'root.'
5634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * before every lhs identifier.
5644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *
5654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         */
5664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        for (dst = &semproc->acc_scripts[0], semproc->acc_scripts[0] = '\0', i = 0; i < raw_scripts_buf.num_scripts; ++i)
5674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
5684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (raw_scripts_buf.list[i].ruleName && raw_scripts_buf.list[i].expression &&
5694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    raw_scripts_buf.list[i].ruleName != WORD_NOT_FOUND &&
5704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    raw_scripts_buf.list[i].expression != WORD_NOT_FOUND)
5714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
5724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (!LSTRCMP(raw_scripts_buf.list[i].expression, L(";")))
5734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    continue;
5744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* set the rule name in a temporary buffer and in the dst */
5754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                src = raw_scripts_buf.list[i].ruleName;
5764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                p = ruleName;
5774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                while (*src && *src != END_SCOPE_MARKER) /* trim off the trailing closing brace END_SCOPE_MARKER */
5784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
5794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    CHKLOG(rc, append_with_check(&dst, *src, &semproc->acc_scripts[MAX_SCRIPT_LEN-1]));
5804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    CHKLOG(rc, append_with_check(&p, *src, &ruleName[31]));
5814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    ++src;
5824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
5834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* put a dot after the rule name, and before the lhs */
5864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                CHKLOG(rc, append_with_check(&dst, L('.'), &semproc->acc_scripts[MAX_SCRIPT_LEN-1]));
5874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                CHKLOG(rc, append_with_check(&p, L('.'), &ruleName[31]));
5884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* terminate the ruleName string */
5904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                CHKLOG(rc, append_with_check(&p, 0, &ruleName[31]));
5914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* append the rest of the expression */
5934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                src = raw_scripts_buf.list[i].expression;
5944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                while (ESR_TRUE)
5964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
5974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /* get the LHS identifier, append to dst, and store temporarily
5984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            in lhs buffer*/
5994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    p = lhs;
6004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    while (*src && *src != '=')
6014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
6024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        CHKLOG(rc, append_with_check(&dst, *src, &semproc->acc_scripts[MAX_SCRIPT_LEN-1]));
6034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        CHKLOG(rc, append_with_check(&p, *src, &lhs[MAX_STRING_LEN-1]));
6044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        ++src;
6054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
6064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /* terminate the lhs string */
6074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    CHKLOG(rc, append_with_check(&p, 0, &lhs[MAX_STRING_LEN-1]));
6084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /* prepend every occurrence of the LHS identifier with 'ruleName.'*/
6104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    for (; *src && *src != ';'; src += tokenLen)
6114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
6124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        const LCHAR* p2;
6134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        tokenLen = get_next_token_len(src);
6154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        if (IS_LOCAL_IDENTIFIER(src, tokenLen)  /* || !LSTRCMP(token, lhs) */)
6164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        {
6174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            /* use p to copy stuff now */
6184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            p = ruleName;
6194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            while (*p)
6204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            {
6214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                /* prepend the rule name to the identifier */
6224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                CHKLOG(rc, append_with_check(&dst, *p, &semproc->acc_scripts[MAX_SCRIPT_LEN-1]));
6234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                ++p;
6244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            }
6254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        }
6264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        for (p2 = src; p2 < src + tokenLen; ++p2)
6274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            CHKLOG(rc, append_with_check(&dst, *p2, &semproc->acc_scripts[MAX_SCRIPT_LEN-1]));
6284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
6304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /*
6324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                     * In an expression there may be several statements, each perhaps with a
6334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                     * new LHS identifier
6344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                     */
6354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /* skip extra semicolons */
6374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    while (*src == ';')
6384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        ++src;
6394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /* skip whitespace */
6404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    while (isspace(*src))
6414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        ++src;
6424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    if (!*src)
6444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
6454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        /* if end of the expression */
6464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        /* terminate the eScript expression properly */
6474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        CHKLOG(rc, append_with_check(&dst, L(';'), &semproc->acc_scripts[MAX_SCRIPT_LEN-1]));
6484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        *dst = '\0';/* terminate the string, DO NOT DO ++ !!! possibility of next loop iteration
6494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                       which will concatenate to the dst string */
6504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        break;
6514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
6524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    else
6534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
6544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        /* concat a single semi-colon */
6554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        CHKLOG(rc, append_with_check(&dst, L(';'), &semproc->acc_scripts[MAX_SCRIPT_LEN-1]));
6564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        p = ruleName;
6574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        while (*p)
6584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        {
6594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            /* prepend the rule name for the new statement */
6604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            CHKLOG(rc, append_with_check(&dst, *p, &semproc->acc_scripts[MAX_SCRIPT_LEN-1]));
6614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            ++p;
6624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        }
6634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
6644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
6654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
6664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
6674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (0) PLogMessage( L("Accumulated Scripts for:\n%s"), semproc->acc_scripts);
6684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (&results[resultIdx] != NULL) /* SemanticResultImpl assumed to have been created externally */
6694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            interpretScripts(semproc, semproc->acc_scripts, &results[resultIdx]);
6704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /**
6724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * Fill in the 'meaning', if it is not there
6734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *  map 'ROOT.meaning' to 'meaning'
6744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *
6754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * NOTE: I am reusing some vars even though the names are a little bit inappropriate.
6764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         */
6774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        hashmap = ((SR_SemanticResultImpl*)results[resultIdx])->results;
6784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        LSTRCPY(meaning, L("meaning"));
6804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, hashmap->containsKey(hashmap, meaning, &containsKey));
6814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (!containsKey)
6824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
6834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            LSTRCPY(meaning, ruleName); /* the last rule name encountered is always the root */
6844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            LSTRCAT(meaning, L("meaning"));
6854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            CHKLOG(rc, hashmap->containsKey(hashmap, meaning, &containsKey));
6864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (containsKey)
6884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
6894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                CHKLOG(rc, hashmap->get(hashmap, meaning, (void **)&p));
6904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* create a new memory location to hold the meaning... not the same as the other cause
6914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         I do not want memory destroy problems */
6924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* add one more space */
6934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                dst = MALLOC(sizeof(LCHAR) * (LSTRLEN(p) + 1), L("semproc.meaning"));
6944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (dst == NULL)
6954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
6964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    rc = ESR_OUT_OF_MEMORY;
6974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    PLogError(ESR_rc2str(rc));
6984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    goto CLEANUP;
6994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
7004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                LSTRCPY(dst, p);
7014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                rc = hashmap->put(hashmap, L("meaning"), dst);
7024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (rc != ESR_SUCCESS)
7034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
7044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    FREE(dst);
7054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    PLogError(ESR_rc2str(rc));
7064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    goto CLEANUP;
7074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
7084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                dst = NULL;
7094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
7104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else
7114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
7124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /*
7134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 * No meaning was provided, so just concat all the values that are associated with the ROOT rule
7144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 * (key name begins with ROOT)
7154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 */
7164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                meaning[0] = 0;
7174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                CHKLOG(rc, hashmap->getSize(hashmap, &size));
7184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                for (j = 0; j < size; j++)
7194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
7204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    CHKLOG(rc, hashmap->getKeyAtIndex(hashmap, j, &p));
7214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    if (LSTRSTR(p, ruleName) == p) /* key name begins with root ruleName */
7224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
7234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        CHKLOG(rc, hashmap->get(hashmap, p, (void **)&dst));
7244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        if (meaning[0] != 0) /* separate vals with space */
7254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        {
7264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            if (LSTRLEN(meaning) + 1 < MAX_STRING_LEN)
7274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                LSTRCAT(meaning, L(" "));
7284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            /* chopping the meaning is harmless */
7294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        }
7304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        if (LSTRLEN(meaning) + LSTRLEN(dst) < MAX_STRING_LEN)
7314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        {
7324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            /* strcat a max of 32 chars */
7334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            LCHAR* p, *pp;
7344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            for (pp = &meaning[0]; *pp != 0; pp++) ; /* scan to the end */
7354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            for (p = dst; *p != 0 && p - dst < 32;) *pp++ = *p++; /* catenate up to 32 chars */
7364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            *pp++ = 0; /* null terminate */
7374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            /* LSTRCAT(meaning,dst); */
7384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        }
7394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        /* chopping the meaning is harmless */
7404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
7414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
7424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (meaning[0] != 0)
7434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
7444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    dst = MALLOC(sizeof(LCHAR) * (LSTRLEN(meaning) + 1), L("semproc.meaning"));
7454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    if (dst == NULL)
7464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
7474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        rc = ESR_OUT_OF_MEMORY;
7484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        PLogError(ESR_rc2str(rc));
7494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        goto CLEANUP;
7504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
7514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    LSTRCPY(dst, meaning);
7524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    rc = hashmap->put(hashmap, L("meaning"), dst);
7534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    if (rc != ESR_SUCCESS)
7544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
7554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        FREE(dst);
7564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        PLogError(ESR_rc2str(rc));
7574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        goto CLEANUP;
7584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
7594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    dst = NULL;
7604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
7614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
7624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
7634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
7644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_SUCCESS;
7664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
7674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return rc;
7684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
7694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/**
7714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Parse the graph
7724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
7734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode SR_SemanticProcessor_CheckParse(SR_SemanticProcessor* self,
7744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                               SR_SemanticGraph* graph,
7754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                               const LCHAR* transcription,
7764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                               SR_SemanticResult** results,
7774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                               size_t* resultCount)
7784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
7794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sem_partial_path *path_root;
7804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    script_list raw_scripts_buf;
7814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LCHAR acc_scripts[MAX_SCRIPT_LEN];  /* the accumulated scripts */
7824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LCHAR lhs[MAX_STRING_LEN];
7834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LCHAR meaning[MAX_STRING_LEN];      /* special key */
7844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LCHAR ruleName[MAX_STRING_LEN];
7854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LCHAR prepared_transcription[MAX_STRING_LEN+1]; /*for final double null */
7864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    size_t i, j, size, resultIdx;
7874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LCHAR* dst = NULL;
7884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LCHAR* p = NULL;
7894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    size_t tokenLen = 0;
7904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const LCHAR* src;
7914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    HashMap* hashmap = NULL;
7924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ESR_ReturnCode rc;
7934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ESR_BOOL containsKey;
7944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sem_partial_path heap[MAX_SEM_PARTIAL_PATHS];
7954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SR_SemanticProcessorImpl* semproc  = (SR_SemanticProcessorImpl*) self;
7964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SR_SemanticGraphImpl* semgraph = (SR_SemanticGraphImpl*) graph;
7974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LSTRCPY(ruleName, L(""));
7994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    CHKLOG(rc, sem_partial_path_list_init(heap, sizeof(heap)/sizeof(heap[0])));
8004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    path_root = sem_partial_path_create(heap);
8014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!path_root)
8024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
8034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rc = ESR_INVALID_STATE;
8044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        goto CLEANUP;
8054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
8064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /**
8084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     * prepare the transcription for processing
8094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     * split words by inserting NULL
8104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     * term by inserting double NULL at end
8114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     */
8124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (i = 0; transcription[i] && i < MAX_STRING_LEN - 2; i++)
8134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
8144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (transcription[i] == L(' '))
8154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            prepared_transcription[i] = 0;
8164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else
8174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            prepared_transcription[i] = transcription[i];
8184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
8194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    prepared_transcription[i] = prepared_transcription[i+1] = 0; /* double null */
8204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /**
8224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     * Parse the graph
8234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     */
8244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
8254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    debug_base_arc_token = &semgraph->arc_token_list[0];
8264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    debug_depth = 0;
8274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
8284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    rc = checkpath_forward(semgraph, heap, &semgraph->arc_token_list[0], path_root, prepared_transcription);
8294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (rc == ESR_NO_MATCH_ERROR)
8304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
8314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        *resultCount = 0;
8324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return ESR_SUCCESS; /* did not parse */
8334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
8344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (rc == ESR_SUCCESS)
8354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
8364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (*resultCount > 0)
8374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            *resultCount = 1;
8384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else
8394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
8404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            /**
8414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             * If the array to hold the results is not big enough,
8424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             * then tell the user right away by returning ESR_BUFFER_OVERFLOW
8434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       with the size required returned in resultCount */
8444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            rc = ESR_BUFFER_OVERFLOW;
8454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            PLogError(ESR_rc2str(rc));
8464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            goto CLEANUP;
8474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
8484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
8494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (rc == ESR_INVALID_STATE)
8504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        goto CLEANUP;
8514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* create the array of Semantic Result Pointers */
8534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (resultIdx = 0; resultIdx < *resultCount; resultIdx++)
8544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
8554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        raw_scripts_buf.num_scripts = 0;
8564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        for (i = 0; i < MAX_SCRIPTS; i++)
8574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
8584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            raw_scripts_buf.list[i].expression = 0;
8594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            raw_scripts_buf.list[i].ruleName = 0;
8604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
8614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /*
8634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * Go through the partial paths which were successful and accumulate the scripts
8644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * that you encountered (BUGGY)
8654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         */
8664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, accumulate_scripts(semgraph, &raw_scripts_buf, path_root));
8674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, sem_partial_path_free(heap, path_root));
8684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /*pfprintf(PSTDOUT,"Accumulated scripts\n");*/
8704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /*
8724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * Prepare the scripts for processing, in other words, make them "nice".
8734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * What I mean by making them nice is to do stuff like:
8744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *
8754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * if ruleName is:   root}
8764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *    expression is: meaning='hello';meaning=meaning+' '+'world';
8774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *
8784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * what I want to accumulate is
8794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *    root.meaning='hello';root.meaning=root.meaning+' '+'world';
8804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *
8814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * I am basically replacing END_SCOPE_MARKER with '.'  and inserting 'root.'
8824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * before every lhs identifier.
8834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *
8844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         */
8854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        for (dst = &acc_scripts[0], acc_scripts[0] = '\0', i = 0; i < raw_scripts_buf.num_scripts; ++i)
8864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
8874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (raw_scripts_buf.list[i].ruleName && raw_scripts_buf.list[i].expression &&
8884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    raw_scripts_buf.list[i].ruleName != WORD_NOT_FOUND &&
8894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    raw_scripts_buf.list[i].expression != WORD_NOT_FOUND)
8904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
8914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (!LSTRCMP(raw_scripts_buf.list[i].expression, L(";")))
8924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    continue;
8934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* set the rule name in a temporary buffer and in the dst */
8944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                src = raw_scripts_buf.list[i].ruleName;
8954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                p = ruleName;
8964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* trim off the trailing closing brace END_SCOPE_MARKER */
8974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                while (*src && *src != END_SCOPE_MARKER)
8984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
8994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    CHKLOG(rc, append_with_check(&dst, *src, &acc_scripts[MAX_SCRIPT_LEN-1]));
9004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    CHKLOG(rc, append_with_check(&p, *src, &ruleName[MAX_STRING_LEN-1]));
9014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    ++src;
9024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
9034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* put a dot after the rule name, and before the lhs */
9064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                CHKLOG(rc, append_with_check(&dst, L('.'), &acc_scripts[MAX_SCRIPT_LEN-1]));
9074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                CHKLOG(rc, append_with_check(&p, L('.'), &ruleName[MAX_STRING_LEN-1]));
9084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* terminate the ruleName string */
9104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                CHKLOG(rc, append_with_check(&p, 0, &ruleName[MAX_STRING_LEN-1]));
9114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* append the rest of the expression */
9134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                src = raw_scripts_buf.list[i].expression;
9144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                while (ESR_TRUE)
9164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
9174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /* get the LHS identifier, append to dst, and store temporarily in lhs buffer*/
9184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    p = lhs;
9194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    while (*src && *src != '=')
9204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
9214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        CHKLOG(rc, append_with_check(&dst, *src, &acc_scripts[MAX_SCRIPT_LEN-1]));
9224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        CHKLOG(rc, append_with_check(&p, *src, &lhs[MAX_STRING_LEN-1]));
9234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        ++src;
9244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
9254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /* terminate the lhs string */
9264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    CHKLOG(rc, append_with_check(&p, 0, &lhs[MAX_STRING_LEN-1]));
9274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /* prepend every occurrence of the LHS identifier with 'ruleName.'*/
9294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    for (; *src && *src != ';'; src += tokenLen)
9304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
9314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        const LCHAR* p2;
9324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        tokenLen = get_next_token_len(src);
9344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        if (IS_LOCAL_IDENTIFIER(src, tokenLen)  /* || !LSTRCMP(token, lhs) */)
9354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        {
9364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            /* use p to copy stuff now */
9374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            p = ruleName;
9384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            while (*p)
9394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            {
9404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                /* prepend the rule name to the identifier */
9414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                CHKLOG(rc, append_with_check(&dst, *p, &acc_scripts[MAX_SCRIPT_LEN-1]));
9424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                ++p;
9434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            }
9444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        }
9454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        for (p2 = src; p2 < src + tokenLen; ++p2)
9464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            CHKLOG(rc, append_with_check(&dst, *p2, &acc_scripts[MAX_SCRIPT_LEN-1]));
9474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
9484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    /*
9504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                     * In an expression there may be several statements, each perhaps with a
9514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                     * new LHS identifier
9524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                     */
9534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    while (*src == ';')
9554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        ++src; /* skip the double triple... semi-colons*/
9564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    if (!*src)
9584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
9594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        /* if end of the expression */
9604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        /* terminate the eScript expression properly */
9614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        CHKLOG(rc, append_with_check(&dst, L(';'), &acc_scripts[MAX_SCRIPT_LEN-1]));
9624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        *dst = '\0';/* terminate the string, DO NOT DO ++ !!! possibility of next loop iteration
9634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                       which will concatenate to the dst string */
9644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        break;
9654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
9664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    else
9674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
9684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        /* concat a single semi-colon */
9694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        CHKLOG(rc, append_with_check(&dst, L(';'), &acc_scripts[MAX_SCRIPT_LEN-1]));
9704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        p = ruleName;
9714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        while (*p)
9724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        {
9734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            /* prepend the rule name for the new statement */
9744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            CHKLOG(rc, append_with_check(&dst, *p, &acc_scripts[MAX_SCRIPT_LEN-1]));
9754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            ++p;
9764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        }
9774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
9784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
9794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
9804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
9814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if defined( SREC_ENGINE_VERBOSE_LOGGING)
9824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        PLogMessage(L("Accumulated Scripts for (%s):\n%s"), transcription, acc_scripts);
9834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
9844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (&results[resultIdx] != NULL) /* SemanticResultImpl assumed to have been created externally */
9854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            interpretScripts(semproc, acc_scripts, &results[resultIdx]);
9864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /**
9884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * Fill in the 'meaning', if it is not there
9894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *  map 'ROOT.meaning' to 'meaning'
9904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *
9914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * NOTE: I am reusing some vars even though the names are a little bit inappropriate.
9924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         */
9934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        hashmap = ((SR_SemanticResultImpl*)results[resultIdx])->results;
9944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        LSTRCPY(meaning, L("meaning"));
9964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, hashmap->containsKey(hashmap, meaning, &containsKey));
9974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (!containsKey)
9984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
9994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            LSTRCPY(meaning, ruleName); /* the last rule name encountered is always the root */
10004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            LSTRCAT(meaning, L("meaning"));
10014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            CHKLOG(rc, hashmap->containsKey(hashmap, meaning, &containsKey));
10024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (containsKey)
10044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
10054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                CHKLOG(rc, hashmap->get(hashmap, meaning, (void **)&p));
10064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* create a new memory location to hold the meaning... not the same as the other cause
10074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         I do not want memory destroy problems */
10084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* add one more space */
10094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                dst = MALLOC(sizeof(LCHAR) * (LSTRLEN(p) + 1), L("semproc.meaning"));
10104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (dst == NULL)
10114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
10124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    rc = ESR_OUT_OF_MEMORY;
10134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    PLogError(ESR_rc2str(rc));
10144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    goto CLEANUP;
10154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
10164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                LSTRCPY(dst, p);
10174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                CHKLOG(rc, hashmap->put(hashmap, L("meaning"), dst));
10184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                dst = NULL;
10194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
10204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else
10214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* absolutely no meaning was provided, so just concat all the values that are associated
10224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 * with the ROOT rule (key name begins with ROOT) */
10234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
10244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                meaning[0] = 0;
10254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                CHKLOG(rc, hashmap->getSize(hashmap, &size));
10264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                for (j = 0; j < size; j++)
10274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
10284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    CHKLOG(rc, hashmap->getKeyAtIndex(hashmap, j, &p));
10294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    if (LSTRSTR(p, ruleName) == p) /* key name begins with root ruleName */
10304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
10314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        CHKLOG(rc, hashmap->get(hashmap, p, (void **)&dst));
10324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        if (meaning[0] != 0) /* separate vals with space */
10334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            LSTRCAT(meaning, L(" "));
10344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        LSTRCAT(meaning, dst);
10354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
10364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
10374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (meaning[0] != 0)
10384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
10394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    dst = MALLOC(sizeof(LCHAR) * (LSTRLEN(meaning) + 1), L("semproc.meaning"));
10404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    if (dst == NULL)
10414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    {
10424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        rc = ESR_OUT_OF_MEMORY;
10434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        PLogError(ESR_rc2str(rc));
10444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        goto CLEANUP;
10454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    }
10464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    LSTRCPY(dst, meaning);
10474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    CHKLOG(rc, hashmap->put(hashmap, L("meaning"), dst));
10484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    dst = NULL;
10494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
10504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
10514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
10524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
10534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_SUCCESS;
10554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
10564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (dst != NULL) FREE(dst);
10574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return rc;
10584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
10594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/**
10614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * After parsing, interpret the acumulated scripts
10624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
10634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode interpretScripts(SR_SemanticProcessorImpl* semproc,
10644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        LCHAR* scripts, SR_SemanticResult** result)
10654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
10664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ESR_ReturnCode rc;
10674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SR_SemanticResultImpl** impl = (SR_SemanticResultImpl**) result;
10684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if ((rc = LA_Analyze(semproc->analyzer, scripts)) == ESR_SUCCESS)
10704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
10714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /****************************
10724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * If all goes well, then the result
10734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         * will be written to the HashMap provided
10744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         ****************************/
10754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if ((rc = EP_parse(semproc->parser, semproc->analyzer, semproc->symtable, semproc->eval, &((*impl)->results))) != ESR_SUCCESS)
10764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            pfprintf(PSTDOUT, "Semantic Result: Error (%s) could not interpret\n", ESR_rc2str(rc));
10774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
10784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return rc;
10794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
10804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/***************************************************************/
10864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* PartialPath stuff                                           */
10874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/***************************************************************/
10884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode sem_partial_path_list_init(sem_partial_path* heap, int nheap)
10904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
10914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int i;
10924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (i = 0; i < MAX_SEM_PARTIAL_PATHS - 1; i++)
10934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        heap[i].next = &heap[i+1];
10944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    heap[i].next = 0;
10954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_SUCCESS;
10964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
10974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic sem_partial_path* sem_partial_path_create(sem_partial_path* heap)
10994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
11004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sem_partial_path* path = heap->next;
11014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (path == NULL)
11024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /* PLogError() is dangerous here, because the stack is very deep */
11044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        pfprintf(PSTDERR, "sem_partial_path_create() no more partial paths available (limit=%d)\n", MAX_SEM_PARTIAL_PATHS);
11054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return NULL;
11064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    heap->next = path->next;
11094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    path->next = NULL;
11114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    path->arc_for_pp = NULL;
11124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return path;
11134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
11144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_CPF
11164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic void sem_partial_path_print(sem_partial_path* path,
11174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        sem_partial_path* paths, int npaths, wordmap* ilabels)
11184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
11194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int i;
11204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sem_partial_path* frompath = 0;
11214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arc_token* a;
11224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!path)
11244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf("--- END ---\n");
11264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return;
11274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf("path %p arc %d %p ", path, (path->arc_for_pp-debug_base_arc_token),
11294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project           path->arc_for_pp);
11304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if ((a = path->arc_for_pp) != NULL)
11314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf(" ilabel %d(%s) olabel %d\n",
11334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project               a->ilabel, ilabels->words[a->ilabel],
11344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project               a->olabel);
11354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else
11374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf("\n");
11394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf(" from ");
11414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (i = 0; i < npaths; i++)
11424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (paths[i].next == path)
11444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
11454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            frompath = &paths[i];
11464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            break;
11474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
11484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (1)sem_partial_path_print(frompath, paths, npaths, ilabels);
11504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
11514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
11524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode sem_partial_path_free(sem_partial_path* heap, sem_partial_path* path)
11544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
11554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    path->next = heap->next;
11564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    heap->next = path;
11574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_SUCCESS;
11584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
11594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/***********************************************************************/
11614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const LCHAR* lookUpWord(SR_SemanticGraphImpl* semgraph, wordID wdid)
11644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
11654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int wdID = wdid;
11664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int mid_offset, upper_offset;
11674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    wordmap* mid_words;
11684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    wordmap* upper_words;
11694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (wdID < 0 || wdID >= MAXwordID)
11714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return WORD_NOT_FOUND;
11724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (semgraph->scopes_olabel_offset < semgraph->script_olabel_offset)
11744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        mid_offset   = semgraph->scopes_olabel_offset;
11764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        mid_words    = semgraph->scopes_olabels;
11774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        upper_offset = semgraph->script_olabel_offset;
11784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        upper_words  = semgraph->scripts;
11794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else
11814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        mid_offset   = semgraph->script_olabel_offset;
11834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        mid_words    = semgraph->scripts;
11844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        upper_offset = semgraph->scopes_olabel_offset;
11854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        upper_words  = semgraph->scopes_olabels;
11864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (wdID < mid_offset && wdID < semgraph->ilabels->num_words)
11894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return semgraph->ilabels->words[wdID];
11914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (wdID >= mid_offset && wdID < upper_offset)
11934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        wdID -= mid_offset;
11954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (wdID >= 0 && wdID < mid_words->num_words)
11964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            return mid_words->words[wdID];
11974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (wdID >= upper_offset && wdID < MAXwordID)
11994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
12004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        wdID -= upper_offset;
12014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (wdID >= 0 && wdID < upper_words->num_words)
12024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            return upper_words->words[wdID];
12034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
12044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return WORD_NOT_FOUND;
12064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
12074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const LCHAR* lookUpScript(SR_SemanticGraphImpl* semgraph, const LCHAR* script_label)
12094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
12104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    size_t index;
12114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    index = atoi(&script_label[1]); /* skip the prepended '_' */
12134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (index > semgraph->scripts->num_words)
12154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return WORD_NOT_FOUND;
12164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else
12174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return semgraph->scripts->words[index];
12184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
12194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectPINLINE ESR_BOOL isnum(const LCHAR* str)
12214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
12224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!str || !*str)
12234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return ESR_FALSE;
12244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (*str)
12264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
12274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (!isdigit(*str))
12284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            return ESR_FALSE;
12294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        str++;
12304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
12314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_TRUE;
12324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
12334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode accumulate_scripts(SR_SemanticGraphImpl* semgraph,
12364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        script_list* scripts, sem_partial_path* path)
12374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
12384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    size_t scope = 0;
12394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arc_token* atok;
12404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sem_partial_path* p;
12414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const LCHAR* word;
12424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    size_t j;
12434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ESR_ReturnCode rc;
12444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (p = path; p != NULL; p = p->next)
12464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
12474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        atok = p->arc_for_pp;
12484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (atok == NULL)
12494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            continue;
12504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else if (atok->ilabel == WORD_EPSILON_LABEL && atok->olabel == WORD_EPSILON_LABEL)
12514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            continue;
12524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else if (atok->olabel != WORD_EPSILON_LABEL)
12534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
12544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            LCHAR* _tMp;
12554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            word = lookUpWord(semgraph, atok->olabel);
12564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if ( IS_BEGIN_SCOPE(word))
12584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                ++scope;
12594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else if ( IS_END_SCOPE(word) )
12604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
12614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                j = scripts->num_scripts;
12624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                do
12634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
12644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    if (scripts->list[j].ruleName == (LCHAR*) scope) /* just an ID */
12654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        scripts->list[j].ruleName = word;
12664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    --j;
12674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
12684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                while (j != (size_t) - 1);
12694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (scope > 0)
12704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    --scope;
12714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                else
12724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
12734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    rc = ESR_INVALID_STATE;
12744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    PLogError(L("ESR_INVALID_STATE: Tried popping scope when it was zero"));
12754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    goto CLEANUP;
12764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
12774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
12784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else
12794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
12804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* make sure it is actually a script */
12814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (wordmap_find_index(semgraph->scripts, word) != MAXwordID)
12824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                {
12834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    MEMCHK(rc, scripts->num_scripts, MAX_SCRIPTS);
12844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    scripts->list[scripts->num_scripts].expression = word;
12854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    scripts->list[scripts->num_scripts].ruleName = (LCHAR*) scope; /* just an ID */
12864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    ++scripts->num_scripts;
12874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
12884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                /* else ignore */
12894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
12904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
12914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
12924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_SUCCESS;
12934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
12944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return rc;
12954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
12964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode SR_SemanticProcessor_SetParam(SR_SemanticProcessor* self,
12984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        const LCHAR* key, const LCHAR* value)
12994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
13004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SR_SemanticProcessorImpl* impl = (SR_SemanticProcessorImpl*) self;
13014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
13024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (self == NULL || key == NULL || value == NULL)
13034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
13044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        PLogError(L("ESR_INVALID_ARGUMENT"));
13054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return ESR_INVALID_ARGUMENT;
13064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
13074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
13084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ST_putSpecialKeyValue(impl->symtable, key, value);
13094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
13104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
13114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
13124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode SR_SemanticProcessor_Flush(SR_SemanticProcessor* self)
13134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
13144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SR_SemanticProcessorImpl* impl = (SR_SemanticProcessorImpl*) self;
13154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
13164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (self == NULL)
13174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
13184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        PLogError(L("ESR_INVALID_ARGUMENT"));
13194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return ESR_INVALID_ARGUMENT;
13204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
13214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ST_reset_all(impl->symtable);
13224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1323