parser.c
来自「agentspark 机器人模拟代码 适用robocup 机器人步态模拟仿真(」· C语言 代码 · 共 1,254 行 · 第 1/3 页
C
1,254 行
sx->val_used = val_used;
sx->val_allocated = val_allocated;
sx->next = NULL;
if (squoted == 1) {
sx->aty = SEXP_SQUOTE;
squoted = 0;
} else
sx->aty = SEXP_DQUOTE;
val = (char *)malloc(sizeof(char)*sexp_val_start_size);
assert(val != NULL);
val_allocated = sexp_val_start_size;
val_used = 0;
vcur = val;
if (!empty_stack (stack))
{
data = (parse_data_t *) top_data (stack);
if (data->fst == NULL)
{
data->fst = data->lst = sx;
}
else
{
data->lst->next = sx;
data->lst = sx;
}
}
else
{
/* looks like this expression was just a basic double
quoted atom - so return it. */
t++; /* spin past the quote */
cc->mode = mode;
cc->squoted = 0;
cc->error = 0;
cc->val = val;
cc->val_used = val_used;
cc->val_allocated = val_allocated;
cc->vcur = vcur;
cc->lastPos = t++;
cc->depth = depth;
cc->qdepth = qdepth;
cc->state = 1;
cc->stack = stack;
cc->esc = 0;
cc->last_sexp = sx;
assert(sx != NULL);
return cc;
}
}
else
{
vcur[0] = t[0];
val_used++;
if (val_used == val_allocated) {
val = (char *)realloc(val,val_allocated+sexp_val_grow_size);
assert(val != NULL);
vcur = val + val_used;
val_allocated += sexp_val_grow_size;
} else vcur++;
if (t[0] == '\\') {
esc = 1;
} else
esc = 0;
}
t++;
break;
case 6:
vcur = val;
state = 1;
break;
case 7:
if (t[0] == '\"')
{
state = 5;
vcur = val;
t++;
vcur[0] = '\"';
val_used++;
if (val_used == val_allocated) {
val = (char *)realloc(val,val_allocated+sexp_val_grow_size);
assert(val != NULL);
vcur = val + val_used;
val_allocated += sexp_val_grow_size;
} else vcur++;
squoted = 1;
}
else if (t[0] == '(')
{
vcur = val;
state = 8;
}
else
{
vcur = val;
state = 4;
squoted = 1;
}
break;
case 8:
if (esc == 0) {
if (t[0] == '(')
{
qdepth++;
}
else if (t[0] == ')')
{
qdepth--;
state = 9;
}
else if (t[0] == '\"')
{
state = 10;
}
} else {
esc = 0;
}
vcur[0] = t[0];
if (t[0] == '\\') esc = 1;
else esc = 0;
val_used++;
if (val_used == val_allocated) {
val = (char *)realloc(val,val_allocated+sexp_val_grow_size);
assert(val != NULL);
vcur = val + val_used;
val_allocated += sexp_val_grow_size;
} else vcur++;
t++;
/* let it fall through to state 9 if we know we're transitioning
into that state */
if (state != 9)
break;
case 9:
if (qdepth == 0)
{
state = 1;
vcur[0] = '\0';
sx = sexp_t_allocate();
assert(sx!=NULL);
elts++;
sx->ty = SEXP_VALUE;
sx->val = val;
sx->val_allocated = val_allocated;
sx->val_used = val_used;
sx->next = NULL;
sx->aty = SEXP_SQUOTE;
val = (char *)malloc(sizeof(char)*sexp_val_start_size);
assert(val != NULL);
val_allocated = sexp_val_start_size;
val_used = 0;
vcur = val;
if (!empty_stack (stack))
{
data = (parse_data_t *) top_data (stack);
if (data->fst == NULL)
{
data->fst = data->lst = sx;
}
else
{
data->lst->next = sx;
data->lst = sx;
}
}
else
{
/* looks like the whole expression was a single
quoted value! So return it. */
cc->mode = mode;
cc->error = 0;
cc->squoted = 0;
cc->val = val;
cc->val_used = val_used;
cc->val_allocated = val_allocated;
cc->vcur = vcur;
cc->lastPos = t;
cc->depth = depth;
cc->qdepth = qdepth;
cc->state = 1;
cc->stack = stack;
cc->esc = 0;
cc->last_sexp = sx;
assert(sx != NULL);
return cc;
}
}
else
state = 8;
break;
case 10:
if (t[0] == '\"' && esc == 0)
{
state = 8;
}
vcur[0] = t[0];
if (t[0] == '\\') esc = 1;
else esc = 0;
val_used++;
if (val_used == val_allocated) {
val = (char *)realloc(val,val_allocated+sexp_val_grow_size);
assert(val != NULL);
vcur = val + val_used;
val_allocated += sexp_val_grow_size;
} else vcur++;
t++;
break;
case 11:
if (t[0] == '\n') {
state = 1;
}
t++;
break;
case 12: /* pre: we saw a # and we're in inline binary mode */
vcur[0] = t[0];
if (t[0] == '\\') esc = 1;
else esc = 0;
val_used++;
if (val_used == val_allocated) {
val = (char *)realloc(val,val_allocated+sexp_val_grow_size);
assert(val != NULL);
vcur = val + val_used;
val_allocated += sexp_val_grow_size;
} else vcur++;
if (t[0] == 'b') {
state = 13; /* so far, #b */
} else {
state = 4; /* not #b, so plain ol' atom */
}
t++;
break;
case 13: /* pre: we saw a #b and we're in inline binary mode */
vcur[0] = t[0];
if (t[0] == '\\') esc = 1;
else esc = 0;
val_used++;
if (val_used == val_allocated) {
val = (char *)realloc(val,val_allocated+sexp_val_grow_size);
assert(val != NULL);
vcur = val + val_used;
val_allocated += sexp_val_grow_size;
} else vcur++;
if (t[0] == '#') {
state = 14; /* so far, #b# - we're definitely in binary
land now. */
/* reset vcur to val, overwrite #b# with the size string. */
vcur = val;
val_used = 0;
} else {
state = 4; /* not #b#, so plain ol' atom */
}
t++;
break;
case 14:
/**
* so far we've read #b#. Now, the steps of the process become:
* proceed to read bytes in until we see # again. This will be
* an ASCII representation of the size. At this point, we want
* to read as many bytes as specified by this size string after
* the #.
*/
if (t[0] == '#') { /* done with size string */
t++;
state = 15;
vcur[0] = '\0';
binexpected = atoi(val);
assert(binexpected > 0);
binread = 0;
bindata = (char *)malloc(sizeof(char)*binexpected);
assert(bindata != NULL);
} else { /* still reading size string */
vcur[0] = t[0];
if (t[0] == '\\') esc = 1;
else esc = 0;
val_used++;
if (val_used == val_allocated) {
val = (char *)realloc(val,val_allocated+sexp_val_grow_size);
assert(val != NULL);
vcur = val + val_used;
val_allocated += sexp_val_grow_size;
} else vcur++;
t++;
}
break;
case 15: /* reading binary blob */
bindata[binread] = t[0];
binread++;
t++;
if (binread == binexpected) {
/* state = 1 -- create a sexp_t and head back */
sx = sexp_t_allocate();
assert(sx!=NULL);
elts++;
sx->ty = SEXP_VALUE;
sx->bindata = bindata;
sx->binlength = binread;
sx->next = NULL;
sx->aty = SEXP_BINARY;
bindata = NULL;
binread = binexpected = 0;
state = 1;
val_used = 0;
vcur = val;
if (!empty_stack (stack))
{
data = (parse_data_t *) top_data (stack);
if (data->fst == NULL)
{
data->fst = data->lst = sx;
}
else
{
data->lst->next = sx;
data->lst = sx;
}
}
}
break;
default:
fprintf (stderr, "Unknown parser state %d.\n", state);
break;
}
/* the null check used to be part of the guard on the while loop.
unfortunately, if we're in state 15, null is considered a
perfectly valid byte. This means the length passed in better
be accurate for the parser to not walk off the end of the
string! */
if (state != 15 && t[0] == '\0') keepgoing = 0;
}
#ifdef _DEBUG_
fprintf(stderr,"State Machine Iterations: %d\nMax Paren Depth: %d\n",
fsm_iterations, maxdepth);
#endif /* _DEBUG_ */
if (depth == 0 && elts > 0) {
cc->mode = mode;
cc->error = 0;
cc->val = val;
cc->squoted = squoted;
cc->val_used = val_used;
cc->val_allocated = val_allocated;
cc->vcur = vcur;
cc->lastPos = t;
cc->depth = depth;
cc->qdepth = qdepth;
cc->state = 1;
cc->stack = stack;
cc->esc = 0;
while (stack->top != NULL)
{
lvl = pop (stack);
data = (parse_data_t *) lvl->data;
sx = data->fst;
/* free (data); */
pd_deallocate(data);
lvl->data = NULL;
}
cc->last_sexp = sx;
} else {
cc->mode = mode;
cc->val = val;
cc->esc = esc;
cc->squoted = squoted;
cc->vcur = vcur;
cc->val_allocated = val_allocated;
cc->val_used = val_used;
if (t[0] == '\0' || t == bufEnd)
cc->lastPos = NULL;
else
cc->lastPos = t;
cc->depth = depth;
cc->qdepth = qdepth;
cc->state = state;
cc->stack = stack;
cc->last_sexp = NULL;
cc->error = 0;
}
return cc;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?