#include #include #include #include #include #include #include #include #include "lalex.h" #include "exprpar.h" int parseBool1(); int parseBool2(); int parseBool3(); int parseLevel1(); int parseLevel2(); int parseLevel3(); int parseLevel4(); int parseLevel5(); extern tokenRec currToken; extern fileReader *currFile; int generateStatements(); int generateAssignment(); int generateCondition(); int generateExpr(); int generateAST() { Node *topNode; int error; // Parse the code and generate abstract syntax tree (AST). topNode = generateStatements(&error); } etc etc Node *generateAssignment() { int ret; // assign_statement := identifier '=' expr st_end // | identifier '=' expr IF condition st_end // | identifier '=' expr UNLESS condition st_end // // st_end := ';' | '\n' getToken(&currToken); printf("generateAssignment %s\n", currToken.val.ident); // a . = expr. Remove =. if (!matchTokenId(TOK_ASSIGN, 1)) { parser_error("Missing '=' in assignment\n"); } // a= . expr generateExpr(); // is EOL (end of line)? if (!isStatementEnd()) { // IF (UNLESS) must be on the same line as expr. // a = expr . IF condition // a = expr . UNLESS condition ret = matchTokenId(TOK_IF, 1); if (!ret) matchTokenId(TOK_UNLESS, 1); if (ret) generateCondition(); } if (!matchStatementEnd()) { printf("Missing EOS\n"); } return 1; } int generateCondition() { printf("Condition\n"); return generateExpr(); } int generateExpr() { getToken(&currToken); parseBool1(); // Parser, expression errors ? if (currToken.error) { fprintf(stderr, "Errors...at line %i\n", 0); return 0; } putTokenBack(&currToken); return (1); } int parseBool1() { int oper; parseBool2(); oper = currToken.stype; // >, <, = while (oper == TOK_GT || oper == TOK_LT || oper == '=' || oper == TOK_LE || oper == TOK_GE) { DEBUG("DEBUG: %c\n", oper); getToken(&currToken); parseBool2(); oper = currToken.stype; if (currToken.error) break; } return (1); } int parseBool2() { int oper; parseBool3(); oper = currToken.stype; // '&&' Boolean AND while (oper == TOK_AND) { DEBUG("DEBUG:AND\n"); getToken(&currToken); parseBool3(); oper = currToken.stype; if (currToken.error) break; } return (1); } int parseBool3() { int oper; parseLevel1(); oper = currToken.stype; // '||' boolean OR while (oper == TOK_OR) { DEBUG("DEBUG:OR\n"); getToken(&currToken); parseLevel1(); oper = currToken.stype; if (currToken.error) break; } return (1); } int parseLevel1() { int oper; parseLevel2(); oper = currToken.stype; // + , - while (oper == TOK_PLUS || oper == '-') { DEBUG("DEBUG: %c\n", oper); getToken(&currToken); parseLevel2(); // gen_math(oper); oper = currToken.stype; if (currToken.error) break; } return (1); } int parseLevel2() { int oper; parseLevel3(); oper = currToken.stype; // *, / while (oper == TOK_MUL || oper == TOK_DIV) { DEBUG("DEBUG: %c\n", oper); getToken(&currToken); parseLevel3(); oper = currToken.stype; if (currToken.error) break; } return (1); } int parseLevel3() { parseLevel4(); // '^' Exponential: 2^3 = 8. if (currToken.stype == TOK_EXP ) { getToken(&currToken); parseLevel3(); // Recursively! // gen_math(TOK_EXP); if (currToken.error) return 0; } return (1); } int parseLevel4() { int oper; oper = 0; // unary +/- (3 + -3) if (currToken.stype == '-' || currToken.stype == '+' ) { oper = currToken.stype; getToken(&currToken); } parseLevel5(); if (oper != 0 ) { // Apply unary +/- // -3 = 3 * (-1) // gen_math((int)(oper=='+' ? 'p' : 'm')); } return ( TRUE); } int parseLevel5() { tokenRec val; // Save type val.stype = currToken.stype; // Get value switch (currToken.stype) { //: '('... ) case TOK_PAROPEN: //: (( 2 + 5) * 6 ) getToken(&currToken); parseBool1(); // Has a right parenthesis ')' ? if (currToken.stype != TOK_PARCLOSE ) { // Missing right ')' currToken.error = TRUE; fprintf(stderr,"Missing right )"); } getToken(&currToken); break; case TOK_INT: DEBUG("DEBUG Integer %ld\n", currToken.val.i); getToken(&currToken); break; case TOK_REAL: getToken(&currToken); break; case TOK_STRING: if (currToken.val.s) { // TODO... } getToken(&currToken); break; default: currToken.error = TRUE; } return ( 1 ); } void parser_error(char *_msg) { fprintf(stderr, _msg); }