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; }
struct D_t *parse_D(){ struct D_t *d = malloc(sizeof(struct D_t)); int m = nexttoken(); if(m == M_DEF){ eat_token(); d->kind = D_DEF; m = nexttoken(); if(m == M_ID){ eat_token(); strcpy(d->str,yytext); d->e = parse_E(); m = nexttoken(); if(m == M_SEMIC){ eat_token(); }else{ syntax_error(); } }else{ syntax_error(); } }else{ syntax_error(); } return d; }
Expression *ParserContext::parse_paren_expression() { eat_token(tok_paren_start); Expression *ret = parse_expression(); eat_token(tok_paren_end); return ret; }
Expression *ParserContext::parse_word_expression() { std::string word = curtok()->string(); eat_token(tok_word); if (curtok()->type() == tok_assign) { eat_token(tok_assign); return new AssignExpr(word, parse_expression()); } else if (curtok()->type() == tok_paren_start) { eat_token(tok_paren_start); std::vector<const Expression*> args; while (curtok()->type() != tok_paren_end) { args.push_back(parse_expression()); if (curtok()->type() == tok_comma) eat_token(tok_comma); } eat_token(tok_paren_end); return new FuncCallExpr(word, args); } return new VariableExpr(word); }
/* Statatements */ Statement *ParserContext::parse_while() { eat_token(tok_while); Expression *cond = parse_paren_expression(); AST *block = parse_block(); return new WhileStatement(cond, block); }
AST *ParserContext::parse_block() { AST *ret = 0; if (curtok()->type() == tok_block_start) { eat_token(tok_block_start); if (curtok()->type() == tok_block_end) { ret = new AST(std::vector<const Statement*>()); } else { ret = parse_ast(true); } eat_token(tok_block_end); } else { std::vector<const Statement*> statements; statements.push_back(parse_statement()); ret = new AST(statements); } return ret; }
struct B_t *parse_B(){ struct B_t *b = malloc(sizeof(struct B_t)); int m = nexttoken(); if(m == M_BEGIN){ eat_token(); b->kind = B_BEGIN; b->l = parse_L(); m = nexttoken(); if(m == M_END){ eat_token(); }else{ syntax_error(); } }else if(m == M_PRINT || m == M_READ || m == M_SET || m == M_IF || m == M_WHILE){ b->kind = B_C; b->c = parse_C(); }else{ syntax_error(); } return b; }
Statement *ParserContext::parse_if() { eat_token(tok_if); Expression *cond = parse_paren_expression(); AST *true_block = parse_block(); if (curtok()->type() == tok_else) { AST *false_block = parse_block(); return new IfStatement(cond, true_block, false_block); } return new IfStatement(cond, true_block); }
Statement *ParserContext::parse_def() { eat_token(tok_def); if (curtok()->type() != tok_word) throw SyntaxError("Expected identifier in function definition"); std::string funcname = curtok()->string(); eat_token(tok_word); if (curtok()->type() != tok_paren_start) throw SyntaxError("Expected parenthesis in function definition"); eat_token(tok_paren_start); std::vector<std::string> params; while (curtok()->type() != tok_paren_end) { if (curtok()->type() != tok_word) throw SyntaxError("Parameters must be identifiers in function definitions"); params.push_back(curtok()->string()); eat_token(tok_word); if (curtok()->type() == tok_comma) eat_token(tok_comma); } eat_token(tok_paren_end); return new DefStatement(funcname, params, parse_block()); }
Expression *ParserContext::parse_binary_op_expression(Expression *LHS, int min_prec) { int op_prec = get_prec(curtok()->type()); while (op_prec >= min_prec) { TokenType op = curtok()->type(); eat_token(op); Expression *RHS = parse_primary(); int next_prec = get_prec(curtok()->type()); while (next_prec > op_prec) { RHS = parse_binary_op_expression(RHS, next_prec); next_prec = get_prec(curtok()->type()); } LHS = new BinaryOpExpr(LHS, RHS, op); op_prec = get_prec(curtok()->type()); } return LHS; }
struct E_t *parse_E(){ struct E_t *e = malloc(sizeof(struct E_t)); int m = nexttoken(); if(m == M_ID){ eat_token(); //IDは読み終わった e->kind = E_ID; strcpy(e->str,yytext); }else if(m == M_NUM){ //NUMの場合 eat_token(); e->kind = E_NUM; strcpy(e->str,yytext); }else if(m == M_ADD){ eat_token(); e->kind = E_ADD; e->e_left = parse_E(); e->e_right = parse_E(); }else if(m == M_SUB){ eat_token(); e->kind = E_SUB; e->e_left = parse_E(); e->e_right = parse_E(); }else if(m == M_EQ){ eat_token(); e->kind = E_EQ; e->e_left = parse_E(); e->e_right = parse_E(); }else if(m == M_LESS){ eat_token(); e->kind = E_LESS; e->e_left = parse_E(); e->e_right = parse_E(); }else{ syntax_error(); } return e; }
struct C_t *parse_C(){ struct C_t *c = malloc(sizeof(struct C_t)); int m = nexttoken(); if(m == M_PRINT){ eat_token(); c->kind = C_PRINT; c->e = parse_E(); m = nexttoken(); if(m == M_SEMIC){ eat_token(); }else{ syntax_error(); } }else if(m == M_READ){ eat_token(); c->kind = C_READ; m = nexttoken(); if(m == M_ID){ eat_token(); strcpy(c->str,yytext); m = nexttoken(); if(m == M_SEMIC){ eat_token(); }else{ syntax_error(); } }else{ syntax_error(); } }else if(m == M_SET){ eat_token(); c->kind = C_SET; m = nexttoken(); if(m == M_ID){ eat_token(); strcpy(c->str,yytext); c->e = parse_E(); m = nexttoken(); if(m == M_SEMIC){ eat_token(); }else{ syntax_error(); } }else{ syntax_error(); } }else if(m == M_IF){ eat_token(); c->kind = C_IF; c->e = parse_E(); m = nexttoken(); if(m == M_THEN){ eat_token(); c->b_left = parse_B(); m = nexttoken(); if(m == M_ELSE){ eat_token(); c->b_right = parse_B(); }else{ syntax_error(); } }else{ syntax_error(); } }else if(m == M_WHILE){ eat_token(); c->kind = C_WHILE; c->e = parse_E(); m = nexttoken(); if(m == M_DO){ eat_token(); c->b = parse_B(); }else{ syntax_error(); } }else{ syntax_error(); } return c; }
Expression *ParserContext::parse_string() { Expression *ret = new ValueExpr(curtok()->string()); eat_token(tok_string); return ret; }
Expression *ParserContext::parse_number() { Expression *ret = new ValueExpr(curtok()->number()); eat_token(tok_number); return ret; }
Statement *ParserContext::parse_return() { eat_token(tok_return); return new ReturnStatement(parse_expression()); }