Exemple #1
0
static struct jx_item * jx_parse_item_list( struct jx_parser *s )
{
	jx_token_t t = jx_scan(s);
	if(t==JX_TOKEN_RBRACKET) {
		// empty list
		return 0;
	}

	jx_unscan(s,t);

	struct jx_item *i = jx_item(0,0);

	i->value = jx_parse(s);
	if(!i->value) {
		// error set by deeper layer
		jx_item_delete(i);
		return 0;
	}

	t = jx_scan(s);
	if(t==JX_TOKEN_COMMA) {
		i->next = jx_parse_item_list(s);
	} else if(t==JX_TOKEN_RBRACKET) {
		i->next = 0;
	} else {
		jx_parse_error(s,"array items missing a comma or closing brace");
		jx_item_delete(i);
		return 0;
	}

	return i;
}
Exemple #2
0
static struct jx_pair * jx_parse_pair_list( struct jx_parser *s )
{
	jx_token_t t = jx_scan(s);
	if(t==JX_TOKEN_RBRACE) {
		// empty list
		return 0;
	}

	jx_unscan(s,t);

	struct jx_pair *p = jx_pair(0,0,0);

	p->key = jx_parse(s);
	if(!p->key) {
		// error set by deeper layer
		jx_pair_delete(p);
		return 0;
	}

	if(s->strict_mode) {
		if(p->key->type!=JX_STRING) {
			jx_parse_error(s,"key-value pair must have a string as the key");
			jx_pair_delete(p);
			return 0;
		}
	}

	t = jx_scan(s);
	if(t!=JX_TOKEN_COLON) {
		jx_parse_error(s,"key-value pair must be separated by a colon");
		jx_pair_delete(p);
		return 0;
	}

	p->value = jx_parse(s);
	if(!p->value) {
		// error set by deeper layer
		jx_pair_delete(p);
		return 0;
	}

	t = jx_scan(s);
	if(t==JX_TOKEN_COMMA) {
		p->next = jx_parse_pair_list(s);
	} else if(t==JX_TOKEN_RBRACE) {
		p->next = 0;
	} else {
		jx_parse_error(s,"key-value pairs missing a comma or closing brace");
		jx_pair_delete(p);
		return 0;
	}

	return p;
}
Exemple #3
0
struct jx * jx_parse( struct jx_parser *s )
{
	jx_token_t t = jx_scan(s);

	switch(t) {
	case JX_TOKEN_EOF:
		return 0;
	case JX_TOKEN_LBRACE:
		return jx_object(jx_parse_pair_list(s));
	case JX_TOKEN_LBRACKET:
		return jx_array(jx_parse_item_list(s));
	case JX_TOKEN_STRING:
		return jx_string(s->token);
	case JX_TOKEN_INTEGER:
		return jx_integer(s->integer_value);
	case JX_TOKEN_DOUBLE:
		return jx_double(s->double_value);
	case JX_TOKEN_TRUE:
		return jx_boolean(1);
	case JX_TOKEN_FALSE:
		return jx_boolean(0);
	case JX_TOKEN_NULL:
		return jx_null();
	case JX_TOKEN_SYMBOL:
		if(s->strict_mode) {
			jx_parse_error(s,"symbols are not allowed in strict parsing mode");
			return 0;
		} else {
			return jx_symbol(s->token);
		}
	case JX_TOKEN_RBRACE:
	case JX_TOKEN_RBRACKET:
	case JX_TOKEN_COMMA:
	case JX_TOKEN_COLON:
	case JX_TOKEN_ERROR:
		jx_parse_error(s,"unexpected token");
		return 0;
	}

	/*
	We shouldn't get here, since all the token types
	should be handled above.  But just in case...
	*/

	jx_parse_error(s,"parse error");
	return 0;
}
Exemple #4
0
static void jx_shell_scan_input(jx_shell_scanner_state * state)
{
  /* allocate parser */

  void *jx_Parser = jx_shell_Alloc((void *(*)(size_t)) jx__shell_alloc);
  jx_int tok_type = 0;
  jx_char stack_buffer[SSCANF_BUFSIZE];

  state->context.status = 0;
  state->n_tok_parsed = 0;

  while(!state->context.exhausted) {
    tok_type = jx_scan(state);
    {
      jx_ob token = JX_OB_NULL;
      jx_size st_len = state->cur - state->tok;
      jx_bool skip = JX_FALSE;
#ifdef JX_SHELL_PARSER_DEBUG

      if(1) {
        jx_size i;
        jx_char *c = state->tok;

        if(st_len) {
          printf(" ");
          for(i = 0; i < st_len; i++) {
            printf("%c", *(c++));
          }
          printf("\n");
        }
      }
#endif

      switch (tok_type) {
      case JX_SHELL_ICON:
      case JX_SHELL_FCON:
      case JX_SHELL_SCON:
      case JX_SHELL_IDENT:
        {
          char *buffer = stack_buffer;
          if(st_len >= SSCANF_BUFSIZE) {
            buffer = jx_malloc(st_len + 1);
          }
          if(buffer) {
            jx_os_strncpy(buffer, state->tok, st_len);
            buffer[st_len] = 0;
            switch (tok_type) {
            case JX_SHELL_ICON:
              {
#ifdef JX_64_BIT
                jx_int icon;
                if(jx_os_sscanf(buffer, "%lli", &icon) != 1) {  /* use strtol instead? */
                  icon = 0;
                }
                token = jx_ob_from_int(icon);
#else
                int icon;
                if(jx_os_sscanf(buffer, "%i", &icon) != 1) {    /* use strtol instead? */
                  icon = 0;
                }
#endif
                token = jx_ob_from_int(icon);
              }
              break;
            case JX_SHELL_FCON:
              {
#ifdef JX_64_BIT
                double fcon;
                if(jx_os_sscanf(buffer, "%lf", &fcon) != 1) {   /* use strtof instead? */
                  fcon = 0.0;
                }
#else
                float fcon;
                if(jx_os_sscanf(buffer, "%f", &fcon) != 1) {    /* use strtof instead? */
                  fcon = 0.0F;
                }
#endif
                token = jx_ob_from_float(fcon);
              }
              break;
            case JX_SHELL_SCON:
              buffer[st_len - 1] = 0;
              token = jx_ob_from_str(buffer + 1);
              break;
            case JX_SHELL_IDENT:
              token = jx_ob_from_ident(buffer);
              break;
            }
            if(buffer != stack_buffer)
              jx_free(buffer);
          }
          break;
      case JX_SHELL_TRUE:
          token = jx_ob_from_bool(true);
          break;
      case JX_SHELL_FALSE:
          token = jx_ob_from_bool(false);
          break;
      case JX_SHELL_NULL:
          token = jx_ob_from_null();
          break;
      case JX_SHELL_BUILTIN:
          token = jx_builtin_new_from_selector(0);
          break;
      case JX_SHELL_EOL:
          {
            jx_ob ob = JX_OB_NULL;
            jx_shell_(jx_Parser, JX_SHELL_EOI, ob, &state->context);
            state->n_tok_parsed++;
          }
          break;
      case JX_SHELL_OPEN_RECT_BRACE:
      case JX_SHELL_CLOSE_RECT_BRACE:
      case JX_SHELL_OPEN_CURLY_BRACE:
      case JX_SHELL_CLOSE_CURLY_BRACE:
          /* do nothing */
          break;
      case JX_SHELL_EOI:
          break;
      case JX_SHELL_ERROR:
          state->context.status = JX_STATUS_SYNTAX_ERROR;
          break;
      case JX_SHELL_COMMA:
          break;
      case JX_SHELL_SEMICOLON:
          break;
        }
      }
      if(!skip) {
        jx_shell_(jx_Parser, (int) tok_type, token, &state->context);

        if(!jx_ok(state->context.status))       /* something bad happened */
          break;

        switch (tok_type) {
        case JX_SHELL_EOI:
          {                     /* parse a null token to enable acceptance */
            jx_ob ob = JX_OB_NULL;
            jx_shell_(jx_Parser, 0, ob, &state->context);
          }
          break;
        }
      }

      if(state->context.status) /* accepted or complete */
        break;
      else
        state->n_tok_parsed++;
    }
  }

  if(tok_type == JX_SHELL_EOI) {
    state->context.exhausted = JX_TRUE;
  }

  /* free the parser instance */
  jx_shell_Free(jx_Parser, jx__shell_free);
}