#include #include #include #include #include #include #include "expr.h" #include "lexer.h" #include "tokenkind.h" // error handling void expectedError(const char *expectedStr) { fprintf(stderr, "%zu.%zu: error expected '%s' got '%s'\n", token.pos.line, token.pos.col, expectedStr, strTokenKind(token.kind)); exit(1); } void expected(enum TokenKind tokenKind) { if (tokenKind != token.kind) { expectedError(strTokenKind(tokenKind)); } } // parse functions void parseInputSequence(void); void parseExprStatement(void); const struct Expr *parseExpr(void); const struct Expr *parseTerm(void); const struct Expr *parsePowerExpr(void); const struct Expr *parseUnaryExpr(void); const struct Expr *parseFactor(void); void parseInputSequence(void) { while (token.kind != EOI) { parseExprStatement(); } } void parseExprStatement(void) { const struct Expr *expr = parseExpr(); //printf("> %lf\n", evalExpr(expr)); printExprTree(expr); deleteExpr(expr); expected(SEMICOLON); getToken(); } const struct Expr * parseExpr(void) { const struct Expr *expr = parseTerm(); while (token.kind == PLUS || token.kind == MINUS) { enum TokenKind op = token.kind; getToken(); const struct Expr *exprRight = parseTerm(); if (op == PLUS) { expr = newBinaryExpr(EK_ADD, expr, exprRight); } else { expr = newBinaryExpr(EK_SUB, expr, exprRight); } } return expr; } const struct Expr * parseTerm(void) { const struct Expr *expr = parsePowerExpr(); while (token.kind == ASTERISK || token.kind == SLASH) { enum TokenKind op = token.kind; getToken(); const struct Expr *exprRight = parsePowerExpr(); if (op == ASTERISK) { expr = newBinaryExpr(EK_MUL, expr, exprRight); } else { expr = newBinaryExpr(EK_DIV, expr, exprRight); } } return expr; } const struct Expr * parsePowerExpr(void) { const struct Expr *expr = parseUnaryExpr(); while (token.kind == CARET) { getToken(); const struct Expr *exprRight = parsePowerExpr(); expr = newBinaryExpr(EK_POW, expr, exprRight); } return expr; } const struct Expr * parseUnaryExpr(void) { if (token.kind == PLUS || token.kind == MINUS) { enum TokenKind op = token.kind; getToken(); const struct Expr *expr = parseUnaryExpr(); if (op == MINUS) { return newUnaryExpr(EK_UNARY_MINUS, expr); } return newUnaryExpr(EK_UNARY_PLUS, expr); } return parseFactor(); } const struct Expr * parseFactor(void) { if (token.kind == DEC_LITERAL) { uint64_t uint = strtoull(token.val.cstr, 0, 10); getToken(); return newUnsignedLiteralExpr(uint); } else if (token.kind == HEX_LITERAL) { uint64_t uint = strtoull(token.val.cstr, 0, 10); getToken(); return newUnsignedLiteralExpr(uint); } else if (token.kind == OCT_LITERAL) { uint64_t uint = strtoull(token.val.cstr, 0, 10); getToken(); return newUnsignedLiteralExpr(uint); } else if (token.kind == LPAREN) { getToken(); const struct Expr *expr = parseExpr(); expected(RPAREN); getToken(); return expr; } else { expectedError("factor"); return 0; // never reached } } // test for the parse int main(void) { // we need a current token before we begin parsing getToken(); parseInputSequence(); }