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; } } }
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; }
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(); }
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(); }
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; } } }
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; }
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; }
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); }
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; }
/** * 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; }
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); }
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; } }
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; }