Exemple #1
0
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;
}
Exemple #2
0
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;
    }
}
Exemple #3
0
/*----------------------------------------------------------------------*/
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 */
}
Exemple #4
0
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;
}
Exemple #5
0
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();
}
Exemple #7
0
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();
  }
}
Exemple #8
0
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;
}
Exemple #9
0
/** 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;
}
Exemple #10
0
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);
}
Exemple #11
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 (&param->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;
}
Exemple #12
0
	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;
	}
Exemple #13
0
/*
 *	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;
}
Exemple #14
0
/*
 * 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;
}
Exemple #15
0
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;
    }
    }
}
Exemple #16
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, &param_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;
}
Exemple #17
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;
}
Exemple #18
0
/*
 *	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;
}