libicl_private.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 1,108 行 · 第 1/3 页
C
1,108 行
#include "stdpccts.h"
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "libicl_private.h"
#include "libicl_depr.h"
#include "libicl.h"
#ifdef _WINDOWS
#include "oaa-windows.h"
#endif
#define EXPORT_BORLAND
#ifdef IS_DLL
#define EXPORT_MSCPP __declspec(dllexport)
#else
#define EXPORT_MSCPP
#endif
#ifndef STREQ
#define STREQ(str1, str2) (strcmp((str1), (str2)) == 0)
#endif
char* ICLDATAQSTART = "icldataq(";
size_t ICLDATAQSTARTLEN = 9;
char last_separator = ',';
/*****************************************************************************
* Operators representation
*****************************************************************************/
SOperator operators[] = {
{ ":-", 1 },
{ ":", 1 },
{ "+", 2 },
{ "-", 2 },
{ "*", 3 },
{ "/", 3 },
{ "dummy", -1 }
};
ICLTerm*
icl_NewTermFromDataDebug(char* data, size_t len)
{
return parser_getTermFromStringDebug(data, len);
}
/**
* Add a child to a compound term
*/
void icl_addChild(ICLTerm* compound, ICLTerm* child)
{
ICLListType* children = icl_List(compound);
if(!(icl_IsList(compound) ||
icl_IsGroup(compound) ||
icl_IsStruct(compound))) {
fprintf(stderr, "icl_addChild attempted to add a child to non-compound term\n");
return;
}
if(children != NULL) {
while(children->next != NULL) {
children = children->next;
}
children->next = (ICLListType*)malloc(sizeof(ICLListType));
children->next->elt = child;
children->next->next = NULL;
}
else {
if(icl_IsStruct(compound)) {
ICLStructType* st = (ICLStructType*)compound->p;
children = (ICLListType*)malloc(sizeof(ICLListType));
children->elt = child;
children->next = NULL;
st->args = icl_NewList(children);
}
else if(icl_IsList(compound)) {
ICLListType* lt = (ICLListType*)malloc(sizeof(ICLListType));
compound->p = lt;
lt->elt = child;
lt->next = NULL;
}
else if(icl_IsGroup(compound)) {
ICLGroupType* gt = (ICLGroupType*)compound->p;
children = (ICLListType*)malloc(sizeof(ICLListType));
children->elt = child;
children->next = NULL;
gt->list = children;
}
}
}
/****************************************************************************
* name: icl_stChunkTerm
* purpose: takes a list of terms (comma separated) and returns the first (car)
* and rest (cdr) of the list.
* inputs:
* - char *terms: a list of prolog terms
* outputs:
* - char *aterm: the first term in the list
* - char *restterms: the rest of the terms
* remarks:
* - Terms may be nested arbitrarily deep (eg. a(b(c(d,1)), X).
* - aterm will return a new copy of the first argument, which should
* be free'd when finished using. restterms will return a pointer
* into terms.
* - Term can correctly parse expression with embedded arguments using
* Japanese JIS7 format. JIS7 is the Japanese encoding standard chosen
* for use with the OAA. Three reasons for this choice: 1) it's the
* most popular standard on UNIX machines. 2) 7-bit encoding should
* be TCP/IP and modem friendly. 3) it's easy to parse: JIS7 embeds
* Japanese characters in a quotation-like wrapper, using ESC$B for the
* opening marker and ESC(B for the closing.
* returns:
* TRUE if a term was read, FALSE if a complete term could not be read.
* In the latter case, aterm and restterms returns "" as well--these
* still need to be freed
****************************************************************************/
EXPORT_MSCPP
int EXPORT_BORLAND icl_safeStTerm(char *terms,
size_t len,
char **aterm,
size_t* atermLen,
char **restterms,
size_t* restTermsLen)
{
size_t i;
int n;
int done = FALSE;
int inquotes = FALSE;
int inJIS7 = FALSE;
int inData = FALSE;
int parens = 0;
int seen_something = FALSE;
char* dataStart;
*aterm = NULL;
*restterms = NULL;
if(len == 0) {
*aterm = strdup("");
*atermLen = 0;
*restterms = strdup("");
*restTermsLen = 0;
return FALSE;
}
i = 0;
while ((i < len) && !done) {
/* Check for icldataq() struct */
if(!inData) {
if((i + ICLDATAQSTARTLEN < len) &&
(strncmp(&terms[i], ICLDATAQSTART, ICLDATAQSTARTLEN) == 0)) {
i += ICLDATAQSTARTLEN;
dataStart = (char*)memchr(&terms[i],'"',len);
if(dataStart == NULL) {
*aterm = strdup("");
*atermLen = 0;
*restterms = strdup("");
*restTermsLen = 0;
return FALSE;
}
i += (dataStart - (char*)(&terms[i]));
inData = TRUE;
}
}
else {
if((i < len) &&
(terms[i] == '"')) {
if((i + 1 < len) &&
(terms[i + 1] == '"')) {
// okay double quotes--still looking at data
i += 2;
continue;
}
else {
// done the data--icldataq should now end with a paren, possibly
// with white space, as well.
++i;
while(i < len) {
switch(terms[i]) {
case ')':
inData = FALSE;
break;
case ' ':
case '\n':
case '\t':
break;
default:
*aterm = strdup("");
*atermLen = 0;
*restterms = strdup("");
*restTermsLen = 0;
return FALSE;
}
++i;
if(inData == FALSE) {
break;
}
}
continue;
}
}
}
/* Check for JIS7 Japanese Encoding markers */
if(!inData) {
if(!inJIS7) {
if ((terms[i] == 27) && (terms[i+1] == '$') && (terms[i+2] == 'B')) {
inJIS7 = TRUE;
}
}
else {
if ((terms[i] == 27) && (terms[i+1] == '(') && (terms[i+2] == 'B')) {
inJIS7 = FALSE;
}
}
}
/* If we are not looking at Japanese characters, try to parse the
input. */
if(!inData) {
if (!inJIS7) {
switch (terms[i]) {
case '(':
case '[':
case '{':
if (!inquotes)
parens = parens + 1;
break;
case ')':
case ']':
case '}':
if (!inquotes) {
parens = parens - 1;
if (parens == 0)
done = TRUE;
}
break;
case '\'':
inquotes = !inquotes;
break;
case ',' :
if ((parens == 0) && (inquotes == 0))
done = TRUE;
break;
case ' ':
case '\n':
case '\t':
if ((parens == 0) && (inquotes == 0) && seen_something)
done = TRUE;
break;
default: seen_something = TRUE;
}
}
}
if(!done) {
++i;
}
} /* End while */
if (!parens && !inquotes) {
if (terms[i] == ',')
n = i;
else n = i+1;
*aterm = malloc(n+1);
strncpy(*aterm, terms, n);
(*aterm)[n] = '\0';
*atermLen = n;
++i;
while ((terms[i] != 0) && ((terms[i] == ' ') || (terms[i] == ',')))
++i;
*restterms = &terms[i];
*restTermsLen = len - *atermLen;
return TRUE;
}
else {
*aterm = strdup("");
*atermLen = 0;
*restterms = strdup("");
*restTermsLen = 0;
return FALSE;
}
}
/****************************************************************************
* name: icl_stIsSeparator
* purpose: Returns true if the beginning of next string is a separator
****************************************************************************/
int
icl_stIsSeparator(char *s) {
return (s && ((*s == ',') || (*s == ';') || (*s == '|')));
}
char
icl_stGetLastSeparator() {
return last_separator;
}
/****************************************************************************
* name: icl_stHeadTailPtr
* purpose: takes a comma-separated list of elements and returns a copy of
* the first element and a pointer to the rest of the list.
* inputs:
* - char *terms: a list of terms
* outputs:
* - char *aterm: the first term in the list
* - char *restterms: the rest of the terms
* remarks:
* - Terms may be nested arbitrarily deep (eg. a(b(c(d,1)), X).
* - aterm will return a new copy of the first argument, which should
* be free'd when finished using. restterms will return a pointer
* into terms, which should NOT BE free'd.
* - Term can correctly parse expression with embedded arguments using
* Japanese JIS7 format. JIS7 is the Japanese encoding standard chosen
* for use with the OAA. Three reasons for this choice: 1) it's the
* most popular standard on UNIX machines. 2) 7-bit encoding should
* be TCP/IP and modem friendly. 3) it's easy to parse: JIS7 embeds
* Japanese characters in a quotation-like wrapper, using ESC$B for the
* opening marker and ESC(B for the closing.
* returns:
* TRUE if a term was read, FALSE if a complete term could not be read.
* In the latter case, aterm and restterms returns "" as well.
****************************************************************************/
EXPORT_MSCPP
int EXPORT_BORLAND
icl_safeStHeadTailPtr(char *terms,
size_t len,
char **aterm,
size_t* atermLen,
char **restterms,
size_t* restTermsLen)
{
size_t i;
size_t n;
int done = FALSE;
int inquotes = FALSE;
int inJIS7 = FALSE;
int parens = 0;
int seen_something = FALSE;
int icldataqStart = -1;
int inData = FALSE;
/*
char* buf = NULL;
char* end = NULL;
long rawLen = -1;
long numQuotes = -1;
*/
*aterm = NULL;
*restterms = NULL;
*atermLen = 0;
*restTermsLen = 0;
if(len == 0) {
*aterm = strdup("");
*atermLen = 0;
*restterms = strdup("");
*restTermsLen = 0;
return FALSE;
}
i = 0;
while ((i < len) && !done) {
if(!inData && !inJIS7) {
/* icldataq( */
if((i + ICLDATAQSTARTLEN) < len) {
if(strncmp(&(terms[i]), ICLDATAQSTART, ICLDATAQSTARTLEN) == 0) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?