Пример #1
0
/*
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();
}
Пример #2
0
instruction_ptr Parser::parse_instruction()
{
    if (!ErrorHandler::is_ok())
        return instruction_ptr();
    
    
    save();
    instruction_ptr result = parse_assignment();
    
    if (!result)
    {
        restore();
        result = parse_expression();
    }
    
    if (!result)
        result = parse_if_block();
    
    if (!result)
        result = parse_while_block();
    
    if (!result)
        result = parse_return();
    
    if (!result)
        result = parse_print();
    
    if (!result)
        result = parse_read();
    
    if (result)
        next_line();
    
    return result;
}
Пример #3
0
/**
	слово:
		список в скобках {}
		подстановка выражения в скобках []
*/
int
parse_word(char *text,char **endptr,Tag *toptag) {
	char *p,*s;
	Tag *tag;
	tag=NULL;
	s=text;

	if (s==NULL || isblank(*s)||strchr(EXPTERM,*s)) return 1;
	if (toptag) tag=mark(WORD,text,text,toptag);

	while(*s) {
		p=s;
		switch(*s) {
			case '{' : parse_list(s,&s,tag);break;
			case '[' : parse_command(s,&s,tag);break;
			case '\'': parse_string(s,&s,tag);break;
			case '\"': parse_subst(s,&s,tag);break;
			case '$' : parse_variable(s,&s,tag);break;
			default:
				if (s[0]=='#' && s[1]!='#' && s[1]!='!') {
					parse_macro(s,&s,tag);
				} else if (s[0]=='#' && s[1]=='?' && s[2]=='>') {
					parse_print(s,&s,tag);
				} else if ((s[0]=='-' && isdigit(s[1])) || isdigit(*s))
					parse_numeric(s,&s,tag);
				else
					mark_cspn(CHARS,BLANK EXPTERM "(",s,&s,tag);
		}
		if (strchr(BLANK EXPTERM,*s)) break;
		if (p==s) break;
	}
	if (endptr) *endptr=s;
	return 0;
}
Пример #4
0
/** разобрать "выражение"
	выражение: последовательность слов разделённых пробелами
**/
int
parse_expression(char *text,char **endptr,Tag *toptag) {
	char *s,*p;
	Tag *tag;
	int comma;
	TRACE("");
	if (!text) return 0;
	s=text;
	tag=NULL;
	comma=1;
	if (toptag) tag=mark(EXPR,text,text,toptag);
	while(*s) {
		p=s;
		mark_ctype(NULL,isblank,s,&s,tag);
		if (s[0]==',') {
			/* слова в выражении разделены , */
			if (comma) {
				mark(NIL,s,s,tag);
			}
			mark_len(NULL,1,s,&s,tag);	// отметить ,
			mark_ctype(NULL,isspace,s,&s,tag); // после , разрешён \n
			comma=1;
			continue;
		} else {
			comma=0;
		}
		if (s[0]=='#' && s[1]=='!') parse_comment(s,&s,tag);
		if (s[0]=='#' && s[1]=='?' && s[2]=='>') parse_print(s,&s,tag);
		if (strchr(EXPTERM,*s)) break;
		if ('('==*s) {
			parse_tuple(s,&s,tag);
		} else
			parse_word(s,&s,tag);
		if (p==s) break;
	}
	if (comma) {
		mark(NIL,s,s,tag);
		s++;
	}
	if (endptr) *endptr=s;
	return 0;
}
Пример #5
0
struct predicate*
build_expression_tree (int argc, char *argv[], int end_of_leading_options)
{
  const struct parser_table *parse_entry; /* Pointer to the parsing table entry for this expression. */
  char *predicate_name;		/* Name of predicate being parsed. */
  struct predicate *cur_pred;
  const struct parser_table *entry_close, *entry_print, *entry_open;
  int i, oldi;

  predicates = NULL;

  /* Find where in ARGV the predicates begin by skipping the list of
   * start points.  As a side effect, also figure out which is the
   * first and last start point.
   */
  start_points = argv + end_of_leading_options;
  for (i = end_of_leading_options; i < argc && !looks_like_expression(argv[i], true); i++)
    {
      ++num_start_points;
    }

  /* Enclose the expression in `( ... )' so a default -print will
     apply to the whole expression. */
  entry_open  = find_parser ("(");
  entry_close = find_parser (")");
  entry_print = find_parser ("print");
  assert (entry_open  != NULL);
  assert (entry_close != NULL);
  assert (entry_print != NULL);

  parse_openparen (entry_open, argv, &argc);
  last_pred->p_name = "(";
  predicates->artificial = true;
  parse_begin_user_args (argv, argc, last_pred, predicates);
  pred_sanity_check (last_pred);

  /* Build the input order list. */
  while (i < argc )
    {
      state.already_issued_stat_error_msg = false;
      if (!looks_like_expression (argv[i], false))
	{
	  error (0, 0, _("paths must precede expression: %s"), argv[i]);
	  usage (stderr, 1, NULL);
	}

      predicate_name = argv[i];
      parse_entry = find_parser (predicate_name);
      if (parse_entry == NULL)
	{
	  /* Command line option not recognized */
	  error (EXIT_FAILURE, 0, _("unknown predicate `%s'"), predicate_name);
	}

      /* We have recognised a test of the form -foo.  Eat that,
       * unless it is a predicate like -newerXY.
       */
      if (parse_entry->type != ARG_SPECIAL_PARSE)
	{
	  i++;
	}
      oldi = i;
      if (!(*(parse_entry->parser_func)) (parse_entry, argv, &i))
	{
	  if (argv[i])
	    {
	      if ( (ARG_SPECIAL_PARSE == parse_entry->type) && (i == oldi) )
		{
		  /* The special parse function spat out the
		   * predicate.  It must be invalid, or not tasty.
		   */
		  error (EXIT_FAILURE, 0, _("invalid predicate `%s'"),
			 predicate_name);
		}
	      else
		{
		  error (EXIT_FAILURE, 0, _("invalid argument `%s' to `%s'"),
			 argv[i], predicate_name);
		}
	    }
	  else
	    {
	      /* Command line option requires an argument */
	      error (EXIT_FAILURE, 0,
		     _("missing argument to `%s'"), predicate_name);
	    }
	}
      else
	{
	  last_pred->p_name = predicate_name;

	  /* If the parser consumed an argument, save it. */
	  if (i != oldi)
	    last_pred->arg_text = argv[oldi];
	  else
	    last_pred->arg_text = NULL;
	}
      pred_sanity_check(last_pred);
      pred_sanity_check(predicates); /* XXX: expensive */
    }
  parse_end_user_args (argv, argc, last_pred, predicates);
  if (predicates->pred_next == NULL)
    {
      /* No predicates that do something other than set a global variable
	 were given; remove the unneeded initial `(' and add `-print'. */
      cur_pred = predicates;
      predicates = last_pred = predicates->pred_next;
      free (cur_pred);
      parse_print (entry_print, argv, &argc);
      last_pred->p_name = "-print";
      pred_sanity_check(last_pred);
      pred_sanity_check(predicates); /* XXX: expensive */
    }
  else if (!default_prints (predicates->pred_next))
    {
      /* One or more predicates that produce output were given;
	 remove the unneeded initial `('. */
      cur_pred = predicates;
      predicates = predicates->pred_next;
      pred_sanity_check (predicates); /* XXX: expensive */
      free (cur_pred);
    }
  else
    {
      /* `( user-supplied-expression ) -print'. */
      parse_closeparen (entry_close, argv, &argc);
      last_pred->p_name = ")";
      last_pred->artificial = true;
      pred_sanity_check (last_pred);
      parse_print (entry_print, argv, &argc);
      last_pred->p_name = "-print";
      last_pred->artificial = true;
      pred_sanity_check (last_pred);
      pred_sanity_check (predicates); /* XXX: expensive */
    }

  if (options.debug_options & (DebugExpressionTree|DebugTreeOpt))
    {
      fprintf (stderr, "Predicate List:\n");
      print_list (stderr, predicates);
    }

  /* do a sanity check */
  check_option_combinations (predicates);
  pred_sanity_check (predicates);

  /* Done parsing the predicates.  Build the evaluation tree. */
  cur_pred = predicates;
  eval_tree = get_expr (&cur_pred, NO_PREC, NULL);
  calculate_derived_rates (eval_tree);

  /* Check if we have any left-over predicates (this fixes
   * Debian bug #185202).
   */
  if (cur_pred != NULL)
    {
      /* cur_pred->p_name is often NULL here */
      if (pred_is (cur_pred, pred_closeparen))
	{
	  /* e.g. "find \( -true \) \)" */
	  error (EXIT_FAILURE, 0, _("you have too many ')'"));
	}
      else
	{
	  if (cur_pred->p_name)
	    error (EXIT_FAILURE, 0,
		   _("unexpected extra predicate '%s'"), cur_pred->p_name);
	  else
	    error (EXIT_FAILURE, 0, _("unexpected extra predicate"));
	}
    }

  if (options.debug_options & (DebugExpressionTree|DebugTreeOpt))
    {
      fprintf (stderr, "Eval Tree:\n");
      print_tree (stderr, eval_tree, 0);
    }

  estimate_costs (eval_tree);

  /* Rearrange the eval tree in optimal-predicate order. */
  opt_expr (&eval_tree);

  /* Check that the tree is in normalised order (opt_expr does this) */
  check_normalization (eval_tree, true);

  do_arm_swaps (eval_tree);

  /* Check that the tree is still in normalised order */
  check_normalization (eval_tree, true);

  if (options.debug_options & (DebugExpressionTree|DebugTreeOpt))
    {
      fprintf (stderr, "Optimized Eval Tree:\n");
      print_tree (stderr, eval_tree, 0);
      fprintf (stderr, "Optimized command line:\n");
      print_optlist (stderr, eval_tree);
      fprintf (stderr, "\n");
    }

  return eval_tree;
}
Пример #6
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;
}