📄 parser.c
字号:
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->bindata = bindata; cc->binread = binread; cc->binexpected = binexpected; 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 *)sexp_realloc(val, val_allocated+sexp_val_grow_size, val_allocated); 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 *)sexp_realloc(val, val_allocated+sexp_val_grow_size, val_allocated); 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 *)sexp_realloc(val, val_allocated+sexp_val_grow_size, val_allocated); 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 *)sexp_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->bindata = bindata; cc->binread = binread; cc->binexpected = binexpected; 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 *)sexp_realloc(val, val_allocated+sexp_val_grow_size, val_allocated); 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 */ if (t[0] == 'b') { vcur[0] = t[0]; if (t[0] == '\\') esc = 1; else esc = 0; val_used++; if (val_used == val_allocated) { val = (char *)sexp_realloc(val, val_allocated+sexp_val_grow_size, val_allocated); assert(val != NULL); vcur = val + val_used; val_allocated += sexp_val_grow_size; } else vcur++; state = 13; /* so far, #b */ t++; } else { state = 4; /* not #b, so plain ol' atom */ } break; case 13: /* pre: we saw a #b and we're in inline binary mode */ if (t[0] == '#') { vcur[0] = t[0]; if (t[0] == '\\') esc = 1; else esc = 0; val_used++; if (val_used == val_allocated) { val = (char *)sexp_realloc(val, val_allocated+sexp_val_grow_size, val_allocated); assert(val != NULL); vcur = val + val_used; val_allocated += sexp_val_grow_size; } else vcur++; 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; t++; } else { state = 4; /* not #b#, so plain ol' atom */ } 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 *)sexp_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 *)sexp_realloc(val, val_allocated+sexp_val_grow_size, val_allocated); 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, "cparse_sexp: 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: %lu\nMax Paren Depth: %lu\n", fsm_iterations, maxdepth);#endif /* _DEBUG_ */ if (depth == 0 && elts > 0) { cc->bindata = bindata; cc->binread = binread; cc->binexpected = binexpected; 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; pd_deallocate(data); lvl->data = NULL; } cc->last_sexp = sx; } else { cc->bindata = bindata; cc->binread = binread; cc->binexpected = binexpected; 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -