示例#1
0
文件: parser.cpp 项目: helgefmi/Toy
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;
}
示例#2
0
文件: parse.c 项目: jkdewar/rook
/*----------------------------------------------------------------------*/
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 */
}
示例#3
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;
}
示例#4
0
// Statement
// Parses a single full statement.  In general this means a declaration
// or an expression, but also includes things like return and break
// statements.
StatementNode* Parser::parse_statement()
{
	switch (token_iter->type) {
		// Return statement
		case K_RETURN: {
			return parse_return();
		}

		// Declaration
		case K_CONST:
		case K_VAL:
		case K_VAR:
		case K_FN:
		case K_STRUCT:
		case K_TYPE: {
			return parse_declaration();
		}

		// Expression
		case INTEGER_LIT:
		case FLOAT_LIT:
		case STRING_LIT:
		case RAW_STRING_LIT:
		case LPAREN:
		case IDENTIFIER:
		case OPERATOR:
		case DOLLAR: {
			return parse_expression();
		}

		default: {
			// Error
			std::ostringstream msg;
			msg << "Unknown statement '" << token_iter->text << "'.";
			parsing_error(*token_iter, msg.str());
			throw 0; // Silence warnings about not returning, parsing_error throws anyway
		}
	}
}
示例#5
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;
}
示例#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;
}
示例#7
0
文件: parser.c 项目: stonegao/mirb
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;
    }
    }
}
示例#8
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;
	}