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 + -
显示快捷键?