static ret_t parse_macros_in_buffer (cherokee_buffer_t *buf, cherokee_handler_dirlist_props_t *props) { #define STR_SZ(str) str, CSZLEN(str) parse_if (buf, STR_SZ("size"), props->show_size); parse_if (buf, STR_SZ("date"), props->show_date); parse_if (buf, STR_SZ("user"), props->show_user); parse_if (buf, STR_SZ("group"), props->show_group); parse_if (buf, STR_SZ("icon"), props->show_icons); #undef STR_SZ return ret_ok; }
static struct AstNode *parse_special( struct DomNode *dom, struct ParserState *state) { struct AstNode *result; if ((!err_state() && (result = parse_do_block(dom, state))) || (!err_state() && (result = parse_match(dom, state))) || (!err_state() && (result = parse_if(dom, state))) || (!err_state() && (result = parse_while(dom, state))) || (!err_state() && (result = parse_func_def(dom, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_AND, ast_make_spec_bool_and, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_OR, ast_make_spec_bool_or, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_SET_OF, ast_make_spec_set_of, state))) || (!err_state() && (result = parse_binary(dom, DOM_RES_RANGE_OF, ast_make_spec_range_of, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_ARRAY_OF, ast_make_spec_array_of, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_TUPLE_OF, ast_make_spec_tuple_of, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_POINTER_TO, ast_make_spec_pointer_to, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_FUNCTION, ast_make_spec_function_type, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_TYPE_PRODUCT, ast_make_spec_type_product, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_TYPE_UNION, ast_make_spec_type_union, state))) || (!err_state() && (result = parse_bind(dom, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_PTR, ast_make_spec_ptr, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_PEEK, ast_make_spec_peek, state))) || (!err_state() && (result = parse_binary(dom, DOM_RES_POKE, ast_make_spec_poke, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_BEGIN, ast_make_spec_begin, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_END, ast_make_spec_end, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_INC, ast_make_spec_inc, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_SUCC, ast_make_spec_succ, state)))) { return result; } else { return NULL; } }
/*----------------------------------------------------------------------*/ static ast_statement_t *parse_statement(parse_state_t *p) { token_t *token; token = peek_token(p); if (token == NULL) { return NULL; } else if (test_token(token, TK_ELSE) || test_token(token, TK_END)) { return NULL; } else if (test_token(token, TK_VAR)) { return parse_declare_var(p); } else if (test_token(token, TK_FUNCTION)) { return parse_define_function(p); } else if (test_token(token, TK_RETURN)) { return parse_return(p); } else if (test_token(token, TK_IF)) { return parse_if(p); } else if (test_token(token, TK_FOR)) { return parse_for(p); } else if (test_token(token, TK_IDENTIFIER)) { return parse_assignment(p); } next_token(p); error(p, "statement expected"); return NULL; /* unreachable */ }
static statement_t* parse_statement(parser_t* p) { statement_t* statement = (statement_t*)malloc(sizeof(statement_t)); token_type_t tok = get_token(p->t); unget_token(p->t); switch (tok) { case TT_IF: statement->type = ST_IF; statement->value = parse_if(p); break; case TT_WHILE: statement->type = ST_WHILE; statement->value = parse_while(p); break; case TT_RETURN: statement->type = ST_RETURN; match(p, TT_RETURN); statement->value = parse_expression(p); break; case TT_PRINT: statement->type = ST_PRINT; match(p, TT_PRINT); statement->value = parse_expression(p); break; default: statement->type = ST_EXPRESSION; statement->value = parse_expression(p); } return statement; }
Statement *ParserContext::parse_statement() { Statement *statement = 0; switch (curtok()->type()) { case tok_while: { statement = parse_while(); break; } case tok_if: { statement = parse_if(); break; } case tok_return: { statement = parse_return(); eat_token(tok_semicolon); break; } case tok_def: { statement = parse_def(); break; } default: { Expression *expression = parse_expression(); if (expression) { statement = new ExpressionStatement(expression); eat_token(tok_semicolon); } else { throw UnexpectedToken("parse_statement", curtok()); } break; } } return statement; }
/* parse_statement Checks the current token to be able to parse the correct statement Parameters: none Return: none */ void parse_statement(Tree &cst){ cst.add_branch_node("statement"); if(!(curr_token -> desc).compare("print")){ parse_print(cst); } else if(!(curr_token -> type).compare("identifier")){ parse_assingment(cst); } else if(types.find(curr_token -> desc) != types.end()){ parse_var_decl(cst); } else if(!(curr_token -> desc).compare("while")){ parse_while(cst); } else if(!(curr_token -> desc).compare("if")){ parse_if(cst); } else if(!(curr_token -> type).compare("open_block")){ parse_block(cst); } else{ std::cout << "Parse Error on line " << curr_token -> line_number << ".\nExpected statement, found " << curr_token -> desc << "\nStatements begin with:\n\tprint\n\tidentifier -- [a-z]\n\t" << "int, string, boolean\n\twhile\n\tif\n\t{" << "\n\nCompilation unsuccessful" << std::endl; exit(EXIT_FAILURE); } cst.kill_all_children(); }
struct instruction *parse_instruction(void) { struct expr *expr; struct instruction *res; switch (lookahead[0]->type) { case WHILE: return parse_while(); case DO: return parse_do(); case IDENTIFIER: case LPAREN: expr = parse_expression(); switch(lookahead[0]->type) { case ASSIGN: return parse_assignment_instr(expr); case EOL: if (expr->exprtype != funcalltype) { if (expr->exprtype == binopexprtype && expr->val.binopexpr.op == EQ) { error(expr->pos, "unexpected =, did you mean <- ?"); exit(1); } else syntaxerror("expected instruction, not expression"); } eat(EOL); res = funcallinstr(expr->val.funcall.fun_ident, expr->val.funcall.args, expr->pos); free(expr); return res; default: next(); syntaxerror("unexpected %s", tok->val); return parse_instruction(); } case RETURN: eat(RETURN); if (lookahead[0]->type == EOL) { eat(EOL); return return_stmt(NULL); } else { expr = parse_expression(); eat(EOL); return return_stmt(expr); } case FOR: return parse_for(); case IF: return parse_if(); case SWITCH: return parse_switch(); case ENDOFFILE: return NULL; default: next(); syntaxerror("expected instruction, not %s", tok->val); return parse_instruction(); } }
struct single *parse_single() { struct single *s; s = parse_io(); if (s != NULL) return s; s = parse_loop(); if (s != NULL) return s; s = parse_if(); if (s != NULL) return s; s = parse_assign(); if (s != NULL) return s; s = parse_gtfo(); if (s != NULL) return s; s = parse_halt(); if (s != NULL) return s; return NULL; }
/** Parse statement. * * @param parse Parser object. * @return New syntax tree node. */ stree_stat_t *parse_stat(parse_t *parse) { stree_stat_t *stat; stree_vdecl_t *vdecl_s; stree_if_t *if_s; stree_switch_t *switch_s; stree_while_t *while_s; stree_for_t *for_s; stree_raise_t *raise_s; stree_break_t *break_s; stree_return_t *return_s; stree_wef_t *wef_s; stree_exps_t *exp_s; #ifdef DEBUG_PARSE_TRACE printf("Parse statement.\n"); #endif switch (lcur_lc(parse)) { case lc_var: vdecl_s = parse_vdecl(parse); stat = stree_stat_new(st_vdecl); stat->u.vdecl_s = vdecl_s; break; case lc_if: if_s = parse_if(parse); stat = stree_stat_new(st_if); stat->u.if_s = if_s; break; case lc_switch: switch_s = parse_switch(parse); stat = stree_stat_new(st_switch); stat->u.switch_s = switch_s; break; case lc_while: while_s = parse_while(parse); stat = stree_stat_new(st_while); stat->u.while_s = while_s; break; case lc_for: for_s = parse_for(parse); stat = stree_stat_new(st_for); stat->u.for_s = for_s; break; case lc_raise: raise_s = parse_raise(parse); stat = stree_stat_new(st_raise); stat->u.raise_s = raise_s; break; case lc_break: break_s = parse_break(parse); stat = stree_stat_new(st_break); stat->u.break_s = break_s; break; case lc_return: return_s = parse_return(parse); stat = stree_stat_new(st_return); stat->u.return_s = return_s; break; case lc_do: case lc_with: wef_s = parse_wef(parse); stat = stree_stat_new(st_wef); stat->u.wef_s = wef_s; break; default: exp_s = parse_exps(parse); stat = stree_stat_new(st_exps); stat->u.exp_s = exp_s; break; } #ifdef DEBUG_PARSE_TRACE printf("Parsed statement %p\n", stat); #endif return stat; }
int parse_config(char *config_file, boolean_t file_required) { FILE *fp; char line[MAXLINELEN]; char pline[MAXLINELEN]; int argcount; char *argvec[MAXARGSPERLINE]; int defaultdone = 0; /* Set when first non-default command found */ if (debug & D_CONFIG) logmsg(LOG_DEBUG, "parse_config()\n"); set_protocol_defaults(); if (debug & D_DEFAULTS) print_defaults(); fp = open_conffile(config_file); if (fp == NULL) { if (errno == ENOENT && !file_required) return (0); logperror(config_file); return (-1); } while (readline(fp, line, sizeof (line)) != 0) { (void) strncpy(pline, line, sizeof (pline)); pline[sizeof (pline) - 1] = '\0'; /* NULL terminate */ argcount = parse_line(pline, argvec, sizeof (argvec) / sizeof (argvec[0])); if (debug & D_PARSE) { int i; logmsg(LOG_DEBUG, "scanned %d args\n", argcount); for (i = 0; i < argcount; i++) logmsg(LOG_DEBUG, "arg[%d]: %s\n", i, argvec[i]); } if (argcount == 0) { /* Empty line - or comment only line */ continue; } if (strcmp(argvec[0], "ifdefault") == 0) { char save[sizeof (ifdefaults)]; if (defaultdone) { conferr("ifdefault after non-default " "command\n"); continue; } /* * Save existing values in case what we read is * invalid and we need to restore previous settings. */ (void) memcpy(save, ifdefaults, sizeof (ifdefaults)); parse_default(CONFIG_IF, iflist, argvec+1, argcount-1, ifdefaults); check_if_var_consistency(ifdefaults, save, sizeof (save)); } else if (strcmp(argvec[0], "prefixdefault") == 0) { char save[sizeof (prefixdefaults)]; if (defaultdone) { conferr("prefixdefault after non-default " "command\n"); continue; } /* * Save existing values in case what we read is * invalid and we need to restore previous settings. */ (void) memcpy(save, prefixdefaults, sizeof (prefixdefaults)); parse_default(CONFIG_PREFIX, prefixlist, argvec+1, argcount-1, prefixdefaults); check_var_consistency(prefixdefaults, save, sizeof (save)); } else if (strcmp(argvec[0], "if") == 0) { defaultdone = 1; parse_if(iflist, argvec+1, argcount-1); } else if (strcmp(argvec[0], "prefix") == 0) { defaultdone = 1; parse_prefix(prefixlist, argvec+1, argcount-1); } else { conferr("Unknown command: %s\n", argvec[0]); } } (void) fclose(fp); if (debug & D_DEFAULTS) print_defaults(); return (0); }
static GLboolean preprocess_source (slang_string *output, const char *source, grammar pid, grammar eid, slang_info_log *elog, const struct gl_extensions *extensions, struct gl_sl_pragmas *pragmas) { static const char *predefined[] = { "__FILE__", "__LINE__", "__VERSION__", #if FEATURE_es2_glsl "GL_ES", "GL_FRAGMENT_PRECISION_HIGH", #endif NULL }; byte *prod; GLuint size, i; pp_state state; if (!grammar_fast_check (pid, (const byte *) (source), &prod, &size, 65536)) { grammar_error_to_log (elog); return GL_FALSE; } pp_state_init (&state, elog, extensions); pp_pragmas_init (pragmas); /* add the predefined symbols to the symbol table */ for (i = 0; predefined[i]; i++) { pp_symbol *symbol = NULL; symbol = pp_symbols_push(&state.symbols); assert(symbol); slang_string_pushs(&symbol->name, predefined[i], _mesa_strlen(predefined[i])); } i = 0; while (i < size) { if (prod[i] != ESCAPE_TOKEN) { if (state.cond.top->effective) { slang_string input; expand_state es; /* Eat only one line of source code to expand it. * FIXME: This approach has one drawback. If a macro with parameters spans across * multiple lines, the preprocessor will raise an error. */ slang_string_init (&input); while (prod[i] != '\0' && prod[i] != '\n') slang_string_pushc (&input, prod[i++]); if (prod[i] != '\0') slang_string_pushc (&input, prod[i++]); /* Increment line number. */ state.line++; es.output = output; es.input = slang_string_cstr (&input); es.state = &state; if (!expand (&es, &state.symbols)) goto error; slang_string_free (&input); } else { /* Condition stack is disabled - keep track on line numbers and output only newlines. */ if (prod[i] == '\n') { state.line++; /*pp_annotate (output, "%c", prod[i]);*/ } else { /*pp_annotate (output, "%c", prod[i]);*/ } i++; } } else { const char *id; GLuint idlen; GLubyte token; i++; token = prod[i++]; switch (token) { case TOKEN_END: /* End of source string. * Check if all #ifs have been terminated by matching #endifs. * On condition stack there should be only the global condition context. */ if (state.cond.top->endif_required) { slang_info_log_error (elog, "end of source without matching #endif."); return GL_FALSE; } break; case TOKEN_DEFINE: { pp_symbol *symbol = NULL; /* Parse macro name. */ id = (const char *) (&prod[i]); idlen = _mesa_strlen (id); if (state.cond.top->effective) { pp_annotate (output, "// #define %s(", id); /* If the symbol is already defined, override it. */ symbol = pp_symbols_find (&state.symbols, id); if (symbol == NULL) { symbol = pp_symbols_push (&state.symbols); if (symbol == NULL) goto error; slang_string_pushs (&symbol->name, id, idlen); } else { pp_symbol_reset (symbol); } } i += idlen + 1; /* Parse optional macro parameters. */ while (prod[i++] != PARAM_END) { pp_symbol *param; id = (const char *) (&prod[i]); idlen = _mesa_strlen (id); if (state.cond.top->effective) { pp_annotate (output, "%s, ", id); param = pp_symbols_push (&symbol->parameters); if (param == NULL) goto error; slang_string_pushs (¶m->name, id, idlen); } i += idlen + 1; } /* Parse macro replacement. */ id = (const char *) (&prod[i]); idlen = _mesa_strlen (id); if (state.cond.top->effective) { slang_string replacement; expand_state es; pp_annotate (output, ") %s", id); slang_string_init(&replacement); slang_string_pushs(&replacement, id, idlen); /* Expand macro replacement. */ es.output = &symbol->replacement; es.input = slang_string_cstr(&replacement); es.state = &state; if (!expand(&es, &state.symbols)) { slang_string_free(&replacement); goto error; } slang_string_free(&replacement); } i += idlen + 1; } break; case TOKEN_UNDEF: id = (const char *) (&prod[i]); i += _mesa_strlen (id) + 1; if (state.cond.top->effective) { pp_symbol *symbol; pp_annotate (output, "// #undef %s", id); /* Try to find symbol with given name and remove it. */ symbol = pp_symbols_find (&state.symbols, id); if (symbol != NULL) if (!pp_symbols_erase (&state.symbols, symbol)) goto error; } break; case TOKEN_IF: { GLint result; /* Parse #if expression end execute it. */ pp_annotate (output, "// #if "); if (!parse_if (output, prod, &i, &result, &state, eid)) goto error; /* Push new condition on the stack. */ if (!pp_cond_stack_push (&state.cond, state.elog)) goto error; state.cond.top->current = result ? GL_TRUE : GL_FALSE; state.cond.top->else_allowed = GL_TRUE; state.cond.top->endif_required = GL_TRUE; pp_cond_stack_reevaluate (&state.cond); } break; case TOKEN_ELSE: /* Check if #else is alloved here. */ if (!state.cond.top->else_allowed) { slang_info_log_error (elog, "#else without matching #if."); goto error; } /* Negate current condition and reevaluate it. */ state.cond.top->current = !state.cond.top->current; state.cond.top->else_allowed = GL_FALSE; pp_cond_stack_reevaluate (&state.cond); if (state.cond.top->effective) pp_annotate (output, "// #else"); break; case TOKEN_ELIF: /* Check if #elif is alloved here. */ if (!state.cond.top->else_allowed) { slang_info_log_error (elog, "#elif without matching #if."); goto error; } /* Negate current condition and reevaluate it. */ state.cond.top->current = !state.cond.top->current; pp_cond_stack_reevaluate (&state.cond); if (state.cond.top->effective) pp_annotate (output, "// #elif "); { GLint result; /* Parse #elif expression end execute it. */ if (!parse_if (output, prod, &i, &result, &state, eid)) goto error; /* Update current condition and reevaluate it. */ state.cond.top->current = result ? GL_TRUE : GL_FALSE; pp_cond_stack_reevaluate (&state.cond); } break; case TOKEN_ENDIF: /* Check if #endif is alloved here. */ if (!state.cond.top->endif_required) { slang_info_log_error (elog, "#endif without matching #if."); goto error; } /* Pop the condition off the stack. */ state.cond.top++; if (state.cond.top->effective) pp_annotate (output, "// #endif"); break; case TOKEN_EXTENSION: /* Parse the extension name. */ id = (const char *) (&prod[i]); i += _mesa_strlen (id) + 1; if (state.cond.top->effective) pp_annotate (output, "// #extension %s: ", id); /* Parse and apply extension behavior. */ if (state.cond.top->effective) { switch (prod[i++]) { case BEHAVIOR_REQUIRE: pp_annotate (output, "require"); if (!pp_ext_set (&state.ext, id, GL_TRUE)) { if (_mesa_strcmp (id, "all") == 0) { slang_info_log_error (elog, "require: bad behavior for #extension all."); goto error; } else { slang_info_log_error (elog, "%s: required extension is not supported.", id); goto error; } } break; case BEHAVIOR_ENABLE: pp_annotate (output, "enable"); if (!pp_ext_set (&state.ext, id, GL_TRUE)) { if (_mesa_strcmp (id, "all") == 0) { slang_info_log_error (elog, "enable: bad behavior for #extension all."); goto error; } else { slang_info_log_warning (elog, "%s: enabled extension is not supported.", id); } } break; case BEHAVIOR_WARN: pp_annotate (output, "warn"); if (!pp_ext_set (&state.ext, id, GL_TRUE)) { if (_mesa_strcmp (id, "all") != 0) { slang_info_log_warning (elog, "%s: enabled extension is not supported.", id); } } break; case BEHAVIOR_DISABLE: pp_annotate (output, "disable"); if (!pp_ext_set (&state.ext, id, GL_FALSE)) { if (_mesa_strcmp (id, "all") == 0) { pp_ext_disable_all (&state.ext); } else { slang_info_log_warning (elog, "%s: disabled extension is not supported.", id); } } break; default: assert (0); } } break; case TOKEN_PRAGMA: { GLint have_param; const char *pragma, *param; pragma = (const char *) (&prod[i]); i += _mesa_strlen(pragma) + 1; have_param = (prod[i++] == PRAGMA_PARAM); if (have_param) { param = (const char *) (&prod[i]); i += _mesa_strlen(param) + 1; } else { param = NULL; } pp_pragma(pragmas, pragma, param); } break; case TOKEN_LINE: id = (const char *) (&prod[i]); i += _mesa_strlen (id) + 1; if (state.cond.top->effective) { slang_string buffer; GLuint count; GLint results[2]; expand_state es; slang_string_init (&buffer); state.line++; es.output = &buffer; es.input = id; es.state = &state; if (!expand (&es, &state.symbols)) goto error; pp_annotate (output, "// #line "); count = execute_expressions (output, eid, (const byte *) (slang_string_cstr (&buffer)), results, state.elog); slang_string_free (&buffer); if (count == 0) goto error; state.line = results[0] - 1; if (count == 2) state.file = results[1]; } break; } } } /* Check for missing #endifs. */ if (state.cond.top->endif_required) { slang_info_log_error (elog, "#endif expected but end of source found."); goto error; } grammar_alloc_free(prod); pp_state_free (&state); return GL_TRUE; error: grammar_alloc_free(prod); pp_state_free (&state); return GL_FALSE; }
bool Parser::parse_statement(StatementList *list) { lexer.identify_keywords(); switch(lexeme()) { case Lexeme::KW_IF: parse_if(list); break; case Lexeme::KW_WHILE: parse_while(list); break; case Lexeme::KW_DO: parse_do(list); parse_terminator(); break; case Lexeme::KW_RETURN: parse_return(list); parse_terminator(); break; case Lexeme::KW_BREAK: parse_break(list); parse_terminator(); break; case Lexeme::KW_CONTINUE: parse_continue(list); parse_terminator(); break; case Lexeme::KW_CONST: step(); parse_local(true, parse_expression(), list); parse_terminator(); break; case Lexeme::BRACET_OPEN: list->append(parse_block<true, false>(Scope::EMPTY)); break; case Lexeme::SEMICOLON: step(); break; case Lexeme::END: case Lexeme::BRACET_CLOSE: return false; default: if(is_expression(lexeme())) { ExpressionNode *node = parse_expression(); if(lexeme() == Lexeme::IDENT && node->is_type_name(document, false)) parse_local(false, node, list); else list->append(node); parse_terminator(); } else return false; } return true; }
/* * Parse one statement. 'foo = bar', or 'if (...) {...}', or '{...}', * and so on. */ static int parse_statement(policy_lex_file_t *lexer, policy_item_t **tail) { int rcode; policy_reserved_word_t reserved; policy_lex_t token, assign; char lhs[256], rhs[256]; policy_assignment_t *this; /* * See what kind of token we have. */ token = policy_lex_file(lexer, 0, lhs, sizeof(lhs)); switch (token) { case POLICY_LEX_LC_BRACKET: rcode = parse_block(lexer, tail); if (!rcode) { return 0; } break; case POLICY_LEX_BARE_WORD: reserved = fr_str2int(policy_reserved_words, lhs, POLICY_RESERVED_UNKNOWN); switch (reserved) { case POLICY_RESERVED_IF: if (parse_if(lexer, tail)) { return 1; } return 0; break; case POLICY_RESERVED_CONTROL: case POLICY_RESERVED_REQUEST: case POLICY_RESERVED_REPLY: case POLICY_RESERVED_PROXY_REQUEST: case POLICY_RESERVED_PROXY_REPLY: if (parse_attribute_block(lexer, tail, reserved)) return 1; return 0; break; case POLICY_RESERVED_PRINT: if (parse_print(lexer, tail)) { return 1; } return 0; break; case POLICY_RESERVED_RETURN: if (parse_return(lexer, tail)) { return 1; } return 0; break; case POLICY_RESERVED_MODULE: if (parse_module(lexer, tail)) { return 1; } return 0; break; case POLICY_RESERVED_UNKNOWN: /* wasn't a reserved word */ /* * Is a named policy, parse the reference to it. */ if (rlm_policy_find(lexer->policies, lhs) != NULL) { if (!parse_call(lexer, tail, lhs)) { return 0; } return 1; } { const DICT_ATTR *dattr; /* * Bare words MUST be dictionary attributes */ dattr = dict_attrbyname(lhs); if (!dattr) { fprintf(stderr, "%s[%d]: Expected attribute name, got \"%s\"\n", lexer->filename, lexer->lineno, lhs); return 0; } debug_tokens("%s[%d]: Got attribute %s\n", lexer->filename, lexer->lineno, lhs); } break; default: fprintf(stderr, "%s[%d]: Unexpected reserved word \"%s\"\n", lexer->filename, lexer->lineno, lhs); return 0; } /* switch over reserved words */ break; /* * Return from nested blocks. */ case POLICY_LEX_RC_BRACKET: policy_lex_push_token(lexer, token); return 2; /* magic */ case POLICY_LEX_EOF: /* nothing more to do */ return 3; default: fprintf(stderr, "%s[%d]: Unexpected %s\n", lexer->filename, lexer->lineno, fr_int2str(policy_explanations, token, "string")); break; } /* * Parse a bare statement. */ assign = policy_lex_file(lexer, 0, rhs, sizeof(rhs)); switch (assign) { case POLICY_LEX_ASSIGN: case POLICY_LEX_SET_EQUALS: case POLICY_LEX_AND_EQUALS: case POLICY_LEX_OR_EQUALS: case POLICY_LEX_PLUS_EQUALS: break; default: fprintf(stderr, "%s[%d]: Unexpected assign %s\n", lexer->filename, lexer->lineno, fr_int2str(policy_explanations, assign, "string")); return 0; } this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_ASSIGNMENT; this->item.lineno = lexer->lineno; token = policy_lex_file(lexer, 0, rhs, sizeof(rhs)); if ((token != POLICY_LEX_BARE_WORD) && (token != POLICY_LEX_DOUBLE_QUOTED_STRING)) { fprintf(stderr, "%s[%d]: Unexpected rhs %s\n", lexer->filename, lexer->lineno, fr_int2str(policy_explanations, token, "string")); rlm_policy_free_item((policy_item_t *) this); return 0; } this->rhs_type = token; this->rhs = strdup(rhs); token = policy_lex_file(lexer, POLICY_LEX_FLAG_RETURN_EOL, rhs, sizeof(rhs)); if (token != POLICY_LEX_EOL) { fprintf(stderr, "%s[%d]: Expected EOL\n", lexer->filename, lexer->lineno); rlm_policy_free_item((policy_item_t *) this); return 0; } debug_tokens("[ASSIGN %s %s %s]\n", lhs, fr_int2str(rlm_policy_tokens, assign, "?"), rhs); /* * Fill in the assignment struct */ this->lhs = strdup(lhs); this->assign = assign; *tail = (policy_item_t *) this; return 1; }
/* * Top level parse function. Input pointer is one complete line from config.in * and the result is that we create a token that describes this line * and insert it into our linked list. */ void parse(char * pnt) { enum token tok; struct kconfig * kcfg; char tmpbuf[24],fake_if[1024]; /* * Ignore comments and leading whitespace. */ pnt = skip_whitespace(pnt); while( *pnt && (*pnt == ' ' || *pnt == '\t')) pnt++; if(! *pnt ) return; if( *pnt == '#' ) return; /* * Now categorize the next token. */ tok = tok_unknown; if (strncmp(pnt, "mainmenu_name", 13) == 0) { tok = tok_menuname; pnt += 13; } else if (strncmp(pnt, "source", 6) == 0) { pnt += 7; pnt = skip_whitespace(pnt); do_source(pnt); return; } else if (strncmp(pnt, "mainmenu_option", 15) == 0) { menus_seen++; tok = tok_menuoption; pnt += 15; } else if (strncmp(pnt, "$MAKE ", 6) == 0) { tok = tok_make; } else if (strncmp(pnt, "comment", 7) == 0) { tok = tok_comment; pnt += 7; } else if (strncmp(pnt, "choice", 6) == 0) { tok = tok_choose; pnt += 6; } else if (strncmp(pnt, "define_bool", 11) == 0) { tok = tok_define; pnt += 11; } else if (strncmp(pnt, "bool", 4) == 0) { tok = tok_bool; pnt += 4; } else if (strncmp(pnt, "tristate", 8) == 0) { tok = tok_tristate; pnt += 8; } else if (strncmp(pnt, "dep_tristate", 12) == 0) { tok = tok_dep_tristate; pnt += 12; } else if (strncmp(pnt, "int", 3) == 0) { tok = tok_int; pnt += 3; } else if (strncmp(pnt, "hex", 3) == 0) { tok = tok_hex; pnt += 3; } else if (strncmp(pnt, "if", 2) == 0) { tok = tok_if; pnt += 2; } else if (strncmp(pnt, "else", 4) == 0) { tok = tok_else; pnt += 4; } else if (strncmp(pnt, "fi", 2) == 0) { tok = tok_fi; pnt += 2; } else if (strncmp(pnt, "endmenu", 7) == 0) { tok = tok_endmenu; pnt += 7; } if( tok == tok_unknown) { if( clast != NULL && clast->tok == tok_if && strcmp(pnt,"then") == 0) return; if( current_file != NULL ) fprintf(stderr, "unknown command=%s(%s %d)\n", pnt, current_file, lineno); else fprintf(stderr, "unknown command=%s(%d)\n", pnt,lineno); return; } /* * Allocate memory for this item, and attach it to the end of the linked * list. */ kcfg = (struct kconfig *) malloc(sizeof(struct kconfig)); memset(kcfg, 0, sizeof(struct kconfig)); kcfg->tok = tok; if( clast != NULL ) { clast->next = kcfg; clast = kcfg; } else { clast = config = kcfg; } pnt = skip_whitespace(pnt); /* * Now parse the remaining parts of the option, and attach the results * to the structure. */ switch (tok) { case tok_choose: pnt = get_qstring(pnt, &kcfg->label); pnt = get_qstring(pnt, &kcfg->optionname); pnt = get_string(pnt, &kcfg->value); /* * Now we need to break apart the individual options into their * own configuration structures. */ parse_choices(kcfg, kcfg->optionname); free(kcfg->optionname); sprintf(tmpbuf, "tmpvar_%d", choose_number++); kcfg->optionname = strdup(tmpbuf); break; case tok_define: pnt = get_string(pnt, &kcfg->optionname); if(*pnt == 'y' || *pnt == 'Y' ) kcfg->value = "1"; if(*pnt == 'n' || *pnt == 'N' ) kcfg->value = "0"; if(*pnt == 'm' || *pnt == 'M' ) kcfg->value = "2"; break; case tok_menuname: pnt = get_qstring(pnt, &kcfg->label); break; case tok_bool: case tok_tristate: pnt = get_qstring(pnt, &kcfg->label); pnt = get_string(pnt, &kcfg->optionname); break; case tok_int: case tok_hex: pnt = get_qstring(pnt, &kcfg->label); pnt = get_string(pnt, &kcfg->optionname); pnt = get_string(pnt, &kcfg->value); break; case tok_dep_tristate: pnt = get_qstring(pnt, &kcfg->label); pnt = get_string(pnt, &kcfg->optionname); pnt = skip_whitespace(pnt); if( *pnt == '$') pnt++; pnt = get_string(pnt, &kcfg->depend.str); /* * Create a conditional for this object's dependency. * * We can't use "!= n" because this is internally converted to "!= 0" * and if UMSDOS depends on MSDOS which depends on FAT, then when FAT * is disabled MSDOS has 16 added to its value, making UMSDOS fully * available. Whew. * * This is more of a hack than a fix. Nested "if" conditionals are * probably affected too - that +/- 16 affects things in too many * places. But this should do for now. */ sprintf(fake_if,"[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" ]; then", kcfg->depend.str,kcfg->depend.str); kcfg->cond = parse_if(fake_if); if(kcfg->cond == NULL ) { exit(1); } break; case tok_comment: pnt = get_qstring(pnt, &kcfg->label); if( koption != NULL ) { pnt = get_qstring(pnt, &kcfg->label); koption->label = kcfg->label; koption = NULL; } break; case tok_menuoption: if( strncmp(pnt, "next_comment", 12) == 0) { koption = kcfg; } else { pnt = get_qstring(pnt, &kcfg->label); } break; case tok_make: kcfg->value=strdup(pnt); break; case tok_else: case tok_fi: case tok_endmenu: break; case tok_if: /* * Conditionals are different. For the first level parse, only * tok_if and tok_dep_tristate items have a ->cond chain attached. */ kcfg->cond = parse_if(pnt); if(kcfg->cond == NULL ) { exit(1); } break; default: exit(0); } return; }
struct node *parse_factor(struct compiler *compiler) { switch (lexer_current(compiler)) { case T_BEGIN: return parse_begin(compiler); case T_IF: return parse_if(compiler); case T_UNLESS: return parse_unless(compiler); case T_CASE: return parse_case(compiler); case T_CLASS: return parse_class(compiler); case T_MODULE: return parse_module(compiler); case T_DEF: return parse_method(compiler); case T_YIELD: return parse_yield(compiler); case T_RETURN: return parse_return(compiler); case T_BREAK: return parse_break(compiler); case T_NEXT: return parse_next(compiler); case T_REDO: return parse_redo(compiler); case T_SQUARE_OPEN: { struct node *result = alloc_node(compiler, N_ARRAY); lexer_next(compiler); if(lexer_current(compiler) == T_SQUARE_CLOSE) result->left = 0; else result->left = parse_array_element(compiler); lexer_match(compiler, T_SQUARE_CLOSE); return result; } case T_STRING: { struct node *result = alloc_node(compiler, N_STRING); result->left = (void *)lexer_token(compiler)->start; lexer_next(compiler); return result; } case T_STRING_START: { struct node *result = alloc_node(compiler, N_STRING_CONTINUE); result->left = 0; result->middle = (void *)lexer_token(compiler)->start; lexer_next(compiler); result->right = parse_statements(compiler); while(lexer_current(compiler) == T_STRING_CONTINUE) { struct node *node = alloc_node(compiler, N_STRING_CONTINUE); node->left = result; node->middle = (void *)lexer_token(compiler)->start; lexer_next(compiler); node->right = parse_statements(compiler); result = node; } if(lexer_require(compiler, T_STRING_END)) { struct node *node = alloc_node(compiler, N_STRING_START); node->left = result; node->right = (void *)lexer_token(compiler)->start; lexer_next(compiler); return node; } return result; } case T_SELF: { lexer_next(compiler); return &self_node; } case T_TRUE: { lexer_next(compiler); return alloc_node(compiler, N_TRUE); } case T_FALSE: { lexer_next(compiler); return alloc_node(compiler, N_FALSE); } case T_NIL: { lexer_next(compiler); return &nil_node; } case T_NUMBER: { struct node *result = alloc_node(compiler, N_NUMBER); char *text = get_token_str(lexer_token(compiler)); result->left = (void* )atoi(text); lexer_next(compiler); return result; } case T_IVAR: { rt_value symbol = rt_symbol_from_lexer(compiler); lexer_next(compiler); switch (lexer_current(compiler)) { case T_ASSIGN_ADD: case T_ASSIGN_SUB: case T_ASSIGN_MUL: case T_ASSIGN_DIV: { struct node *result; enum token_type op_type = lexer_current(compiler) - OP_TO_ASSIGN; lexer_next(compiler); result = alloc_node(compiler, N_IVAR_ASSIGN); result->right = alloc_node(compiler, N_BINARY_OP); result->right->op = op_type; result->right->left = alloc_node(compiler, N_IVAR); result->right->left->left = (void *)symbol; result->right->right = parse_expression(compiler); result->left = (void *)symbol; return result; } case T_ASSIGN: { struct node *result; lexer_next(compiler); result = alloc_node(compiler, N_IVAR_ASSIGN); result->left = (void *)symbol; result->right = parse_expression(compiler); return result; } default: { struct node *result = alloc_node(compiler, N_IVAR); result->left = (void *)symbol; return result; } } } case T_IDENT: return parse_identifier(compiler); case T_EXT_IDENT: return parse_call(compiler, 0, &self_node, false); case T_PARAM_OPEN: { lexer_next(compiler); struct node *result = parse_statements(compiler); lexer_match(compiler, T_PARAM_CLOSE); return result; } default: { COMPILER_ERROR(compiler, "Expected expression but found %s", token_type_names[lexer_current(compiler)]); lexer_next(compiler); return 0; } } }
int assemble(struct _asm_context *asm_context) { char token[TOKENLEN]; int token_type; while(1) { token_type = tokens_get(asm_context, token, TOKENLEN); #ifdef DEBUG printf("%d: <%d> %s\n", asm_context->line, token_type, token); #endif if (token_type == TOKEN_EOF) break; if (token_type == TOKEN_EOL) { if (asm_context->macros.stack_ptr == 0) { asm_context->line++; } } else if (token_type == TOKEN_LABEL) { int param_count_temp; if (macros_lookup(&asm_context->macros, token, ¶m_count_temp) != NULL) { print_already_defined(asm_context, token); return -1; } if (symbols_append(&asm_context->symbols, token, asm_context->address / asm_context->bytes_per_address) == -1) { return -1; } } else if (token_type == TOKEN_POUND || IS_TOKEN(token,'.')) { token_type = tokens_get(asm_context, token, TOKENLEN); #ifdef DEBUG printf("%d: <%d> %s\n", asm_context->line, token_type, token); #endif if (token_type == TOKEN_EOF) break; if (strcasecmp(token, "define") == 0) { if (macros_parse(asm_context, IS_DEFINE) != 0) return -1; } else if (strcasecmp(token, "ifdef") == 0) { parse_ifdef(asm_context, 0); } else if (strcasecmp(token, "ifndef") == 0) { parse_ifdef(asm_context, 1); } else if (strcasecmp(token, "if") == 0) { parse_if(asm_context); } else if (strcasecmp(token, "endif") == 0) { if (asm_context->ifdef_count < 1) { printf("Error: unmatched .endif at %s:%d\n", asm_context->filename, asm_context->ifdef_count); return -1; } return 0; } else if (strcasecmp(token, "else") == 0) { if (asm_context->ifdef_count < 1) { printf("Error: unmatched .else at %s:%d\n", asm_context->filename, asm_context->ifdef_count); return -1; } return 2; } else if (strcasecmp(token, "include") == 0) { if (parse_include(asm_context) != 0) return -1; } else if (strcasecmp(token, "binfile") == 0) { if (parse_binfile(asm_context) != 0) return -1; } else if (strcasecmp(token, "code") == 0) { asm_context->segment = SEGMENT_CODE; } else if (strcasecmp(token, "bss") == 0) { asm_context->segment = SEGMENT_BSS; } else if (strcasecmp(token, "msp430_cpu4") == 0) { asm_context->msp430_cpu4 = 1; } else if (strcasecmp(token, "macro") == 0) { if (macros_parse(asm_context, IS_MACRO) != 0) return -1; } else if (strcasecmp(token, "pragma") == 0) { if (parse_pragma(asm_context) != 0) return -1; } else if (strcasecmp(token, "device") == 0) { if (parse_device(asm_context) != 0) return -1; } else if (strcasecmp(token, "set") == 0) { if (parse_set(asm_context) != 0) return -1; } else if (strcasecmp(token, "export") == 0) { if (parse_export(asm_context) != 0) return -1; } else if (strcasecmp(token, "equ") == 0 || strcasecmp(token, "def")==0) { if (parse_equ(asm_context) != 0) return -1; } else { int ret = check_for_directive(asm_context, token); if (ret == 2) break; if (ret == -1) return -1; if (ret != 1) { printf("Error: Unknown directive '%s' at %s:%d.\n", token, asm_context->filename, asm_context->line); return -1; } } } else if (token_type == TOKEN_STRING) { int ret = check_for_directive(asm_context, token); if (ret == 2) break; if (ret == -1) return -1; if (ret != 1) { int start_address = asm_context->address; char token2[TOKENLEN]; int token_type2; token_type2 = tokens_get(asm_context, token2, TOKENLEN); if (strcasecmp(token2, "equ") == 0) { //token_type2 = tokens_get(asm_context, token2, TOKENLEN); int ptr = 0; int ch = '\n'; while(1) { ch = tokens_get_char(asm_context); if (ch == EOF || ch == '\n') break; if (ch == '*' && ptr > 0 && token2[ptr-1] == '/') { macros_strip_comment(asm_context); ptr--; continue; } token2[ptr++] = ch; if (ptr == TOKENLEN-1) { printf("Internal Error: token overflow at %s:%d.\n", __FILE__, __LINE__); return -1; } } token2[ptr] = 0; tokens_unget_char(asm_context, ch); macros_strip(token2); macros_append(asm_context, token, token2, 0); } else { tokens_push(asm_context, token2, token_type2); ret = asm_context->parse_instruction(asm_context, token); if (asm_context->pass == 2 && asm_context->list != NULL && asm_context->include_count == 0) { asm_context->list_output(asm_context, start_address); fprintf(asm_context->list, "\n"); } if (ret < 0) return -1; if (asm_context->macros.stack_ptr == 0) { asm_context->line++; } asm_context->instruction_count++; if (asm_context->address > start_address) { asm_context->code_count += (asm_context->address - start_address); } } } } else { print_error_unexp(token, asm_context); return -1; } } if (asm_context->error == 1) { return -1; } return 0; }
/* parse a compound- or a simple-command * (pipeline and lists are done outside this) * ----------------------------------------------------------------------- */ union node *parse_command(struct parser *p, int tempflags) { enum tok_flag tok; union node *command; union node **rptr; tok = parse_gettok(p, tempflags); switch(tok) { /* T_FOR begins an iteration statement */ case T_FOR: command = parse_for(p); break; /* T_IF begins a case match statement */ case T_CASE: command = parse_case(p); break; /* T_IF begins a conditional statement */ case T_IF: command = parse_if(p); break; /* T_WHILE/T_UNTIL begin a for-loop statement */ case T_WHILE: case T_UNTIL: command = parse_loop(p); break; /* T_LP/T_BEGIN start a grouping compound */ case T_LP: case T_BEGIN: p->pushback++; command = parse_grouping(p); break; /* handle simple commands */ case T_NAME: case T_WORD: case T_REDIR: case T_ASSIGN: p->pushback++; command = parse_simple_command(p); break; /* it wasn't a compound command, return now */ default: p->pushback++; return NULL; } if(command) { /* they all can have redirections, so parse these now */ rptr = &command->ncmd.rdir; /* * in the case of a simple command there are maybe already * redirections in the list (because in a simple command they * can appear between arguments), so skip to the end of the list. */ while(*rptr) tree_next(rptr); while(parse_gettok(p, P_DEFAULT) & T_REDIR) tree_move(p->tree, rptr); } p->pushback++; return command; }
/* * if (...) {...} * if (...) {...} else {...} * if (...) {...} else if ... */ static int parse_if(policy_lex_file_t *lexer, policy_item_t **tail) { int rcode; policy_lex_t token; char mystring[256]; policy_if_t *this; debug_tokens("[IF] "); this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_IF; this->item.lineno = lexer->lineno; rcode = parse_condition(lexer, &(this->condition)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } rcode = parse_block(lexer, &(this->if_true)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, mystring, sizeof(mystring)); if ((token == POLICY_LEX_BARE_WORD) && (fr_str2int(policy_reserved_words, mystring, POLICY_RESERVED_UNKNOWN) == POLICY_RESERVED_ELSE)) { debug_tokens("[ELSE] "); token = policy_lex_file(lexer, 0, mystring, sizeof(mystring)); rad_assert(token == POLICY_LEX_BARE_WORD); token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, mystring, sizeof(mystring)); if ((token == POLICY_LEX_BARE_WORD) && (fr_str2int(policy_reserved_words, mystring, POLICY_RESERVED_UNKNOWN) == POLICY_RESERVED_IF)) { token = policy_lex_file(lexer, 0, mystring, sizeof(mystring)); rad_assert(token == POLICY_LEX_BARE_WORD); rcode = parse_if(lexer, &(this->if_false)); } else { rcode = parse_block(lexer, &(this->if_false)); } if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } } debug_tokens("\n"); /* * Empty "if" condition, don't even bother remembering * it. */ if (!this->if_true && !this->if_false) { debug_tokens("Discarding empty \"if\" statement at line %d\n", this->item.lineno); rlm_policy_free_item((policy_item_t *) this); return 1; } *tail = (policy_item_t *) this; return 1; }