Beispiel #1
0
static int parse_function_args(ExprParseState *state)
{
  if (!parse_next_token(state) || state->token != '(' || !parse_next_token(state)) {
    return -1;
  }

  int arg_count = 0;

  for (;;) {
    if (!parse_expr(state)) {
      return -1;
    }

    arg_count++;

    switch (state->token) {
      case ',':
        if (!parse_next_token(state)) {
          return -1;
        }
        break;

      case ')':
        if (!parse_next_token(state)) {
          return -1;
        }
        return arg_count;

      default:
        return -1;
    }
  }
}
Beispiel #2
0
int parse_VariablePath(VariablePath *self, parser_t *parser, token_t *token){
	int ret;
	while((ret = parse_next_token(parser, token))!=0){
		if(ret<0)
			return 1; // completed
		
		if(token->type==TOKEN_OPEN){
			self->next = (VariablePath*)calloc(1, sizeof(VariablePath));
			VariablePath_init(self->next);
			parse_VariablePath(self->next, parser, token);
			// Expect a closing brace
			if(parse_next_token(parser, token)<=0 || token->type!=TOKEN_CLOSE)
				return 0;
			// The only thing allowed after a closing brace is plus or end of line
			if(parse_next_token(parser, token) && token->type!=TOKEN_PLUS)
				return 0;
		} 
		else if(token->type==TOKEN_CLOSE){
			// Handling the closing brace is the job of previous level
			parse_return_token(parser, token);
			return 1; 
	 	} 
		else if(token->type == TOKEN_MODULE){
			// Module name
			strncpy(self->module, token->string, sizeof(self->module));
			// Check if there is also an adress after module name
			if(parse_next_token(parser, token)>0){
				if(token->type==TOKEN_PLUS){
					if(parse_next_token(parser, token)>0){
						if(token->type==TOKEN_HEX)
							sscanf(token->string, "%x", (int*)&self->address);
						else if(token->type==TOKEN_INT)
							sscanf(token->string, "%d", (int*)&self->address);
					} else { // any other token is unexpected
						return 0;
					}
				} else { // Return any token other then plus
					parse_return_token(parser, token);
				}
			}
		} 
		else if(token->type == TOKEN_INT){
			// A base address represented by an int 
			sscanf(token->string, "%d", (int*)&self->address);
		} 
		else if(token->type == TOKEN_HEX){
			// A base address in hex
			sscanf(token->string, "%x", (int*)&self->address);
		}
		else // Unexpected token
			return 0;
	}
	return 0;
}
Beispiel #3
0
static bool parse_expr(ExprParseState *state)
{
  /* Temporarily set the constant expression evaluation barrier */
  int prev_last_jmp = state->last_jmp;
  int start = state->last_jmp = state->ops_count;

  CHECK_ERROR(parse_or(state));

  if (state->token == TOKEN_IF) {
    /* Ternary IF expression in python requires swapping the
     * main body with condition, so stash the body opcodes. */
    int size = state->ops_count - start;
    int bytes = size * sizeof(ExprOp);

    ExprOp *body = MEM_mallocN(bytes, "driver if body");
    memcpy(body, state->ops + start, bytes);

    state->last_jmp = state->ops_count = start;
    state->stack_ptr--;

    /* Parse condition. */
    if (!parse_next_token(state) || !parse_or(state) || state->token != TOKEN_ELSE ||
        !parse_next_token(state)) {
      MEM_freeN(body);
      return false;
    }

    int jmp_else = parse_add_jump(state, OPCODE_JMP_ELSE);

    /* Add body back. */
    memcpy(parse_alloc_ops(state, size), body, bytes);
    MEM_freeN(body);

    state->stack_ptr++;

    int jmp_end = parse_add_jump(state, OPCODE_JMP);

    /* Parse the else block. */
    parse_set_jump(state, jmp_else);

    CHECK_ERROR(parse_expr(state));

    parse_set_jump(state, jmp_end);
  }
  /* If no actual jumps happened, restore previous barrier */
  else if (state->last_jmp == start) {
    state->last_jmp = prev_last_jmp;
  }

  return true;
}
Tokenizer::Tokenizer(ProgramReader* pgm)
{
	current_token = END_STATEMENT; // Force a restart on next.
	m_file = pgm;
	curr_str = 0;
	current_line = 0;
	parse_next_token();
}
Beispiel #5
0
static bool parse_not(ExprParseState *state)
{
  if (state->token == TOKEN_NOT) {
    CHECK_ERROR(parse_next_token(state) && parse_not(state));
    parse_add_func(state, OPCODE_FUNC1, 1, op_not);
    return true;
  }

  return parse_cmp(state);
}
void Tokenizer::reset()
{
	current_token = END_STATEMENT;
	current_line = 0;
	current_line_position = 0;
	m_file->seek_begin();
	curr_str = 0;
	curr_int = 0;
	varname = 'a';
	
	parse_next_token();
}
Beispiel #7
0
static bool parse_add(ExprParseState *state)
{
  CHECK_ERROR(parse_mul(state));

  for (;;) {
    switch (state->token) {
      case '+':
        CHECK_ERROR(parse_next_token(state) && parse_mul(state));
        parse_add_func(state, OPCODE_FUNC2, 2, op_add);
        break;

      case '-':
        CHECK_ERROR(parse_next_token(state) && parse_mul(state));
        parse_add_func(state, OPCODE_FUNC2, 2, op_sub);
        break;

      default:
        return true;
    }
  }
}
Beispiel #8
0
static bool parse_or(ExprParseState *state)
{
  CHECK_ERROR(parse_and(state));

  if (state->token == TOKEN_OR) {
    int jump = parse_add_jump(state, OPCODE_JMP_OR);

    CHECK_ERROR(parse_next_token(state) && parse_or(state));

    parse_set_jump(state, jump);
  }

  return true;
}
Beispiel #9
0
static bool parse_cmp(ExprParseState *state)
{
  CHECK_ERROR(parse_add(state));

  BinaryOpFunc func = parse_get_cmp_func(state->token);

  if (func) {
    CHECK_ERROR(parse_next_token(state) && parse_add(state));

    return parse_cmp_chain(state, func);
  }

  return true;
}
Beispiel #10
0
int parser_lex(void *lval, parser_ctx_t *ctx)
{
    int ret;

    while(1) {
        ret = parse_next_token(lval, ctx);
        if(ret != tNL || ctx->last_token != tNL)
            break;

        ctx->last_nl = ctx->ptr-ctx->code;
    }

    return (ctx->last_token = ret);
}
Beispiel #11
0
static bool parse_cmp_chain(ExprParseState *state, BinaryOpFunc cur_func)
{
  BinaryOpFunc next_func = parse_get_cmp_func(state->token);

  if (next_func) {
    parse_add_op(state, OPCODE_CMP_CHAIN, -1)->arg.func2 = cur_func;
    int jump = state->last_jmp = state->ops_count;

    CHECK_ERROR(parse_next_token(state) && parse_add(state));
    CHECK_ERROR(parse_cmp_chain(state, next_func));

    parse_set_jump(state, jump);
  }
  else {
    parse_add_func(state, OPCODE_FUNC2, 2, cur_func);
  }

  return true;
}
Beispiel #12
0
/**
 * Compile the expression and return the result.
 *
 * Parse the expression for evaluation later.
 * Returns non-NULL even on failure; use is_valid to check.
 */
ExprPyLike_Parsed *BLI_expr_pylike_parse(const char *expression,
                                         const char **param_names,
                                         int param_names_len)
{
  /* Prepare the parser state. */
  ExprParseState state;
  memset(&state, 0, sizeof(state));

  state.cur = state.expr = expression;

  state.param_names_len = param_names_len;
  state.param_names = param_names;

  state.tokenbuf = MEM_mallocN(strlen(expression) + 1, __func__);

  state.max_ops = 16;
  state.ops = MEM_mallocN(state.max_ops * sizeof(ExprOp), __func__);

  /* Parse the expression. */
  ExprPyLike_Parsed *expr;

  if (parse_next_token(&state) && parse_expr(&state) && state.token == 0) {
    BLI_assert(state.stack_ptr == 1);

    int bytesize = sizeof(ExprPyLike_Parsed) + state.ops_count * sizeof(ExprOp);

    expr = MEM_mallocN(bytesize, "ExprPyLike_Parsed");
    expr->ops_count = state.ops_count;
    expr->max_stack = state.max_stack;

    memcpy(expr->ops, state.ops, state.ops_count * sizeof(ExprOp));
  }
  else {
    /* Always return a non-NULL object so that parse failure can be cached. */
    expr = MEM_callocN(sizeof(ExprPyLike_Parsed), "ExprPyLike_Parsed(empty)");
  }

  MEM_freeN(state.tokenbuf);
  MEM_freeN(state.ops);
  return expr;
}
Beispiel #13
0
int parser_lex(void *lval, parser_ctx_t *ctx)
{
    int ret;

    while(1) {
        ret = parse_next_token(lval, ctx);
        if(ret == '_') {
            skip_spaces(ctx);
            if(*ctx->ptr != '\n') {
                FIXME("'_' not followed by newline\n");
                return 0;
            }
            ctx->ptr++;
            continue;
        }
        if(ret != tNL || ctx->last_token != tNL)
            break;

        ctx->last_nl = ctx->ptr-ctx->code;
    }

    return (ctx->last_token = ret);
}
Beispiel #14
0
static bool parse_unary(ExprParseState *state)
{
  int i;

  switch (state->token) {
    case '+':
      return parse_next_token(state) && parse_unary(state);

    case '-':
      CHECK_ERROR(parse_next_token(state) && parse_unary(state));
      parse_add_func(state, OPCODE_FUNC1, 1, op_negate);
      return true;

    case '(':
      return parse_next_token(state) && parse_expr(state) && state->token == ')' &&
             parse_next_token(state);

    case TOKEN_NUMBER:
      parse_add_op(state, OPCODE_CONST, 1)->arg.dval = state->tokenval;
      return parse_next_token(state);

    case TOKEN_ID:
      /* Parameters: search in reverse order in case of duplicate names -
       * the last one should win. */
      for (i = state->param_names_len - 1; i >= 0; i--) {
        if (STREQ(state->tokenbuf, state->param_names[i])) {
          parse_add_op(state, OPCODE_PARAMETER, 1)->arg.ival = i;
          return parse_next_token(state);
        }
      }

      /* Ordinary builtin constants. */
      for (i = 0; builtin_consts[i].name; i++) {
        if (STREQ(state->tokenbuf, builtin_consts[i].name)) {
          parse_add_op(state, OPCODE_CONST, 1)->arg.dval = builtin_consts[i].value;
          return parse_next_token(state);
        }
      }

      /* Ordinary builtin functions. */
      for (i = 0; builtin_ops[i].name; i++) {
        if (STREQ(state->tokenbuf, builtin_ops[i].name)) {
          int args = parse_function_args(state);

          return parse_add_func(state, builtin_ops[i].op, args, builtin_ops[i].funcptr);
        }
      }

      /* Specially supported functions. */
      if (STREQ(state->tokenbuf, "min")) {
        int cnt = parse_function_args(state);
        CHECK_ERROR(cnt > 0);

        parse_add_op(state, OPCODE_MIN, 1 - cnt)->arg.ival = cnt;
        return true;
      }

      if (STREQ(state->tokenbuf, "max")) {
        int cnt = parse_function_args(state);
        CHECK_ERROR(cnt > 0);

        parse_add_op(state, OPCODE_MAX, 1 - cnt)->arg.ival = cnt;
        return true;
      }

      return false;

    default:
      return false;
  }
}
Beispiel #15
0
static ya_result
config_section_loggers_set_wild(struct config_section_descriptor_s *csd, const char *key, const char *value)
{
    u32 debuglevel = 0;
    ya_result return_code;
    
    // next word(base,delimiter)
    // 

    bool end_of_level = FALSE;
    
    do
    {
        char level[16];
        
        value = parse_skip_spaces(value);
        
        if(*value == '\0')
        {
            break;
        }
        
        if(FAIL(return_code = parse_next_token(level, sizeof(level), value, SYSLOG_LEVEL_TOKEN_DELIMITER)))
        {
            return return_code;
        }
        
        // if the token has spaces between two chars, then we need to cut
        
        char *end_of_first_word = (char*)parse_next_blank(level); // level is not const
        if(*end_of_first_word != '\0')
        {
            char *start_of_next_word = (char*)parse_skip_spaces(end_of_first_word); // end_of_first_word is not const

            if(start_of_next_word != end_of_first_word)
            {
                // last loop iteration
                
                end_of_level = TRUE;
            }
            
            *end_of_first_word = '\0';
            
            // adjust next word search start
            
            value += end_of_first_word - level + 1;
        }
        else
        {
            value += return_code + 1; // note: false positive from cppcheck
        }
        
        //
        
        u32 debuglevel_value;
        
        if(FAIL(get_value_from_casename(logger_debuglevels, level, &debuglevel_value)))
        {
            return CONFIG_LOGGER_INVALID_DEBUGLEVEL;
        }

        debuglevel |= debuglevel_value;
    }
    while(!end_of_level);
    
    for(;;)
    {
        char channel_name[64];
        
        value = parse_skip_spaces(value);
        
        if(*value == '\0')
        {
            break;
        }
        
        if(FAIL(return_code = parse_next_token(channel_name, sizeof(channel_name), value, SYSLOG_CHANNEL_TOKEN_DELIMITER)))
        {
            return return_code;
        }
                
        if(*channel_name == '\0')
        {
            continue;
        }

        logger_handle_add_channel(key, (int)debuglevel, channel_name);
        
        value += return_code;
        
        if(*value == '\0')
        {
            break;
        }
        
        value++;
    }
    
    return SUCCESS;
}