Browse Source

Finish, but error.

XCBOSA - ITX 3 years ago
parent
commit
011b7a275b
1 changed files with 531 additions and 31 deletions
  1. 531 31
      Exp2_Parser/main.c

+ 531 - 31
Exp2_Parser/main.c

@@ -460,6 +460,9 @@ void lexSetPos(LexState *state, LexStatePos *pos) {
     state->bufSize = pos->bufSize;
 }
 
+#define lgp LexStatePos lp = lexGetPos(state);
+#define lsp lexSetPos(state, &lp);
+
 // MARK: - Parser
 
 Bool parsePlus(LexState *state, FILE *output);
@@ -483,7 +486,7 @@ Bool parseNoReturnFunction(LexState *state, FILE *output);
 Bool parseCompoundStatement(LexState *state, FILE *output);
 Bool parseArgumentTable(LexState *state, FILE *output);
 Bool parseMainFunction(LexState *state, FILE *output);
-Bool parseExpression(LexState *state, FILE *output);
+Bool parseExpression(LexState *state, FILE *output, Bool isFirst);
 Bool parseItem(LexState *state, FILE *output);
 Bool parseFactor(LexState *state, FILE *output);
 Bool parseStatement(LexState *state, FILE *output);
@@ -564,7 +567,16 @@ Bool parseLiterialString(LexState *state, FILE *output) {
 }
 
 Bool parseProgram(LexState *state, FILE *output) {
-    
+    parseConstantDescription(state, output, true);
+    parseVariableDescription(state, output);
+    while (true) {
+        if (parseMainFunction(state, output)) {
+            break;
+        }
+        parseReturnFunction(state, output);
+    }
+    fprintf(output, "<程序>\n");
+    return true;
 }
 
 Bool parseConstantDescription(LexState *state, FILE *output, Bool printIfIs) {
@@ -653,10 +665,7 @@ Bool parseUnsignedNumber(LexState *state, FILE *output) {
 
 Bool parseNumber(LexState *state, FILE *output) {
     LexStatePos lp = lexGetPos(state);
-    if (!parsePlus(state, output)) {
-        lexSetPos(state, &lp);
-        return false;
-    }
+    parsePlus(state, output);
     if (!parseUnsignedNumber(state, output)) {
         lexSetPos(state, &lp);
         return false;
@@ -709,97 +718,588 @@ Bool parseVariableDescription(LexState *state, FILE *output) {
 Bool parseVariableDefinition(LexState *state, FILE *output) {
     LexStatePos lp = lexGetPos(state);
     if (!parseTypeLabel(state, output)) {
-        if type
+        lexSetPos(state, &lp);
+        return false;
+    }
+    if (!parseIdentfication(state, output)) {
+        lexSetPos(state, &lp);
         return false;
     }
+    Token testTk = lexGetToken(state);
+    if (stringEquals(testTk.tokenTy, LBRACK)) {
+        if (!parseUnsignedNumber(state, output)) {
+            printf("Error: array length must be unsigned number.");
+            exit(-1);
+        }
+        Token tk2 = lexGetToken(state);
+        if (!stringEquals(tk2.tokenTy, RBRACK)) {
+            printf("Error: array length not terminated, expect ], but got %s", tk2.tokenBody);
+            exit(-1);
+        }
+    } else {
+        lexPutToken(state, testTk);
+    }
+    Token nextTk = lexGetToken(state);
+    if (stringEquals(nextTk.tokenTy, COMMA)) {
+        if (!parseVariableDefinition(state, output)) {
+            printf("Error: variable definition error, after comma.");
+            exit(-1);
+        }
+    }
+    fprintf(output, "<变量定义>\n");
+    return true;
 }
 
 Bool parseTypeLabel(LexState *state, FILE *output) {
-    
+    Token tok = lexGetToken(state);
+    if (!(stringEquals(tok.tokenTy, INTTK) || stringEquals(tok.tokenTy, CHARTK))) {
+        lexPutToken(state, tok);
+        return false;
+    }
+    return true;
 }
 
 Bool parseReturnFunction(LexState *state, FILE *output) {
-    
+    LexStatePos lp = lexGetPos(state);
+    if (!parseDeclaractionHead(state, output)) {
+        lexSetPos(state, &lp);
+        return false;
+    }
+    Token lparentTok = lexGetToken(state);
+    if (!stringEquals(lparentTok.tokenTy, LPARENT)) {
+        lexSetPos(state, &lp);
+        return false;
+    }
+    if (!parseArgumentTable(state, output)) {
+        lexSetPos(state, &lp);
+        return false;
+    }
+    Token rparentTok = lexGetToken(state);
+    if (!stringEquals(rparentTok.tokenTy, RPARENT)) {
+        lexSetPos(state, &lp);
+        return false;
+    }
+    Token lbraceTok = lexGetToken(state);
+    if (!stringEquals(lbraceTok.tokenTy, LBRACE)) {
+        lexSetPos(state, &lp);
+        return false;
+    }
+    if (!parseCompoundStatement(state, output)) {
+        lexSetPos(state, &lp);
+        return false;
+    }
+    Token rbraceTok = lexGetToken(state);
+    if (!stringEquals(rbraceTok.tokenTy, RBRACE)) {
+        lexSetPos(state, &lp);
+        return false;
+    }
+    fprintf(output, "<有返回值函数定义>\n");
+    return true;
 }
 
 Bool parseNoReturnFunction(LexState *state, FILE *output) {
-    
+    lgp;
+    Token voidTk = lexGetToken(state);
+    if (!stringEquals(voidTk.tokenTy, VOIDTK)) {
+        lsp;
+        return false;
+    }
+    if (!parseIdentfication(state, output)) {
+        lsp;
+        return false;
+    }
+    Token lparentTok = lexGetToken(state);
+    if (!stringEquals(lparentTok.tokenTy, LPARENT)) {
+        lsp;
+        return false;
+    }
+    if (!parseArgumentTable(state, output)) {
+        lsp;
+        return false;
+    }
+    Token rparentTok = lexGetToken(state);
+    if (!stringEquals(rparentTok.tokenTy, RPARENT)) {
+        lsp;
+        return false;
+    }
+    Token lbraceTok = lexGetToken(state);
+    if (!stringEquals(lbraceTok.tokenTy, LBRACE)) {
+        lsp;
+        return false;
+    }
+    if (!parseCompoundStatement(state, output)) {
+        lsp;
+        return false;
+    }
+    Token rbraceTok = lexGetToken(state);
+    if (!stringEquals(rbraceTok.tokenTy, RBRACE)) {
+        lsp;
+        return false;
+    }
+    fprintf(output, "<无返回值函数定义>\n");
+    return true;
 }
 
 Bool parseCompoundStatement(LexState *state, FILE *output) {
-    
+    lgp;
+    parseConstantDescription(state, output, true);
+    parseVariableDescription(state, output);
+    if (!parseStatementList(state, output)) {
+        lsp;
+        return false;
+    }
+    fprintf(output, "<复合语句>\n");
+    return true;
 }
 
 Bool parseArgumentTable(LexState *state, FILE *output) {
-    
+    lgp;
+    if (!parseTypeLabel(state, output)) {
+        lsp;
+        return true; // 空
+    }
+    if (!parseIdentfication(state, output)) {
+        lsp;
+        return false;
+    }
+    Token commaTk = lexGetToken(state);
+    if (stringEquals(commaTk.tokenTy, COMMA)) {
+        if (!parseArgumentTable(state, output)) {
+            printf("Error: Argument table, after ,");
+            exit(-1);
+        }
+    }
+    fprintf(output, "<参数表>\n");
+    return true;
 }
 
 Bool parseMainFunction(LexState *state, FILE *output) {
-    
+    lgp;
+    if (!stringEquals(lexGetToken(state).tokenTy, VOIDTK)) {
+        lsp;
+        return false;
+    }
+    if (!stringEquals(lexGetToken(state).tokenTy, MAINTK)) {
+        lsp;
+        return false;
+    }
+    if (!stringEquals(lexGetToken(state).tokenTy, LPARENT)) {
+        lsp;
+        return false;
+    }
+    if (!stringEquals(lexGetToken(state).tokenTy, RPARENT)) {
+        lsp;
+        return false;
+    }
+    if (!stringEquals(lexGetToken(state).tokenTy, LBRACE)) {
+        lsp;
+        return false;
+    }
+    if (!parseCompoundStatement(state, output)) {
+        lsp;
+        return false;
+    }
+    if (!stringEquals(lexGetToken(state).tokenTy, RBRACE)) {
+        lsp;
+        return false;
+    }
+    fprintf(output, "<主函数>\n");
+    return true;
 }
 
-Bool parseExpression(LexState *state, FILE *output) {
-    
+Bool parseExpression(LexState *state, FILE *output, Bool isFirst) {
+    lgp;
+    Bool hasPlus = parsePlus(state, output);
+    if (!isFirst && !hasPlus) {
+        lsp;
+        return false;
+    }
+    if (!parseItem(state, output)) {
+        lsp;
+        return false;
+    }
+    Token nxt = lexPeekToken(state);
+    if (stringEquals(nxt.tokenTy, PLUS) || stringEquals(nxt.tokenTy, MINU)) {
+        if (!parseExpression(state, output, false)) {
+            printf("Error expression definition.");
+            exit(-1);
+        }
+    }
+    fprintf(output, "<表达式>\n");
+    return true;
 }
 
 Bool parseItem(LexState *state, FILE *output) {
-    
+    lgp;
+    if (!parseFactor(state, output)) {
+        lsp;
+        return false;
+    }
+    if (!parseMult(state, output)) {
+        lsp;
+        return false;
+    }
+    if (!parseFactor(state, output)) {
+        lsp;
+        return false;
+    }
+    while (true) {
+        if (parseMult(state, output)) {
+            if (!parseFactor(state, output)) {
+                printf("Error: Mult Expression Error");
+                exit(-1);
+            }
+        } else {
+            break;
+        }
+    }
+    fprintf(output, "<项>\n");
+    return true;
+}
+
+#define lexPeekIs(tokTy) stringEquals(lexPeekToken(state).tokenTy, tokTy)
+#define lexGetIs(tokTy) stringEquals(lexGetToken(state).tokenTy, tokTy)
+#define lexAssertIs(tokTy) if (!stringEquals(lexGetToken(state).tokenTy, tokTy)) {\
+printf("Error: Expect %s", tokTy); \
+exit(-1); \
+}
+
+#define lexAssertIsOr(tokTy, T2) if (!(stringEquals(lexGetToken(state).tokenTy, tokTy) || stringEquals(lexGetToken(state).tokenTy, T2))) {\
+printf("Error: Expect %s", tokTy); \
+exit(-1); \
+}
+
+#define lexFallback(tokTy) if (!stringEquals(lexGetToken(state).tokenTy, tokTy)) {\
+lsp; \
+return false; \
 }
 
 Bool parseFactor(LexState *state, FILE *output) {
-    
+    lgp;
+    if (parseIdentfication(state, output)) {
+        if (lexPeekIs(LBRACK)) {
+            lexGetToken(state);
+            if (!parseExpression(state, output, true)) {
+                printf("Error: [ need expression");
+                exit(-1);
+            }
+            lexAssertIs(RBRACK);
+        }
+        fprintf(output, "<因子>\n");
+        return true;
+    }
+    lsp;
+    if (lexPeekIs(LPARENT)) {
+        lexGetToken(state);
+        if (!parseExpression(state, output, true)) {
+            printf("Error: ( need expression");
+            exit(-1);
+        }
+        lexAssertIs(RPARENT);
+        fprintf(output, "<因子>\n");
+        return true;
+    }
+    lsp;
+    if (parseNumber(state, output)) {
+        fprintf(output, "<因子>\n");
+        return true;
+    }
+    lsp;
+    if (parseLiterialCHAR(state, output)) {
+        fprintf(output, "<因子>\n");
+        return true;
+    }
+    lsp;
+    if (parseReturnFunction(state, output)) {
+        fprintf(output, "<因子>\n");
+        return true;
+    }
+    lsp;
+    return false;
 }
 
 Bool parseStatement(LexState *state, FILE *output) {
-    
+    lgp;
+    if (parseStatementIf(state, output)) {
+        fprintf(output, "<语句>\n");
+        return true;
+    }
+    lsp;
+    if (parseStatementCycle(state, output)) {
+        fprintf(output, "<语句>\n");
+        return true;
+    }
+    lsp;
+    if (parseStatementList(state, output)) {
+        fprintf(output, "<语句>\n");
+        return true;
+    }
+    lsp;
+    if (parseStatementReturn(state, output)) {
+        fprintf(output, "<语句>\n");
+        return true;
+    }
+    lsp;
+    if (parseStatementFuncCallWithResult(state, output)) {
+        fprintf(output, "<语句>\n");
+        return true;
+    }
+    lsp;
+    if (parseStatementFuncCallWithoutResult(state, output)) {
+        fprintf(output, "<语句>\n");
+        return true;
+    }
+    lsp;
+    if (parseStatementAssign(state, output)) {
+        fprintf(output, "<语句>\n");
+        return true;
+    }
+    lsp;
+    if (parseStatementFuncCallRead(state, output)) {
+        fprintf(output, "<语句>\n");
+        return true;
+    }
+    lsp;
+    if (parseStatementFuncCallWrite(state, output)) {
+        fprintf(output, "<语句>\n");
+        return true;
+    }
+    lsp;
+    if (parseStatementReturn(state, output)) {
+        fprintf(output, "<语句>\n");
+        return true;
+    }
+    lsp;
+    fprintf(output, "<语句>\n");
+    return true; // 空
 }
 
 Bool parseStatementAssign(LexState *state, FILE *output) {
-    
+    lgp;
+    if (!parseIdentfication(state, output)) {
+        lsp;
+        return false;
+    }
+    if (lexPeekIs(LBRACK)) {
+        lexPeekToken(state);
+        if (!parseExpression(state, output, true)) {
+            printf("Error: after [ should be expression.");
+            exit(-1);
+        }
+        lexAssertIs(RBRACK);
+    }
+    if (!lexGetIs(EQL)) {
+        lsp;
+        return false;
+    }
+    if (!parseExpression(state, output, true)) {
+        printf("Error: after = should be expression.");
+        exit(-1);
+    }
+    fprintf(output, "<赋值语句>\n");
+    return true;
+}
+
+#define lexAssertFailback(tokTy) if (!lexGetIs(tokTy)) { \
+lsp; \
+return false; \
 }
 
 Bool parseStatementIf(LexState *state, FILE *output) {
-    
+    lgp;
+    lexAssertFailback(IFTK);
+    lexAssertFailback(LPARENT);
+    if (!parseStatementIfCondition(state, output)) {
+        printf("Error: after if ( should be conditions");
+        exit(-1);
+    }
+    lexAssertIs(RPARENT);
+    if (!parseExpression(state, output, true)) {
+        printf("Error: after { should be expression");
+        exit(-1);
+    }
+    if (lexPeekIs(ELSETK)) {
+        lexGetToken(state);
+        if (!parseStatement(state, output)) {
+            printf("Error: after else should be expression");
+        }
+    }
+    fprintf(output, "<条件语句>\n");
+    return true;
 }
 
 Bool parseStatementIfCondition(LexState *state, FILE *output) {
-    
+    lgp;
+    if (!parseExpression(state, output, true)) {
+        lsp;
+        return false;
+    }
+    if (!parseRelation(state, output)) {
+        lsp;
+        return false;
+    }
+    if (!parseExpression(state, output, true)) {
+        lsp;
+        return false;
+    }
+    fprintf(output, "<条件>\n");
+    return true;
+}
+
+#define parseFallback(parseFunc) if (!parseFunc(state, output)) { \
+lsp; \
+return false; \
+}
+
+#define parseFallback3(parseFunc) if (!parseFunc(state, output, true)) { \
+lsp; \
+return false; \
+}
+
+#define parseAssert(parseFunc) if (!parseFunc(state, output)) { \
+printf("Error: parse error"); \
+exit(-1); \
+}
+
+#define parseAssert3(parseFunc) if (!parseFunc(state, output, true)) { \
+printf("Error: parse error"); \
+exit(-1); \
 }
 
 Bool parseStatementCycle(LexState *state, FILE *output) {
-    
+    lgp;
+    Token cycleTyTk = lexGetToken(state);
+    if (stringEquals(cycleTyTk.tokenTy, WHILETK)) {
+        lexAssertIs(LPARENT);
+        parseAssert(parseStatementIfCondition);
+        lexAssertIs(RPARENT);
+        parseAssert3(parseExpression);
+    } else if (stringEquals(cycleTyTk.tokenTy, DOTK)) {
+        parseAssert(parseStatement);
+        lexAssertIs(WHILETK);
+        lexAssertIs(LPARENT);
+        parseAssert(parseStatementIfCondition);
+        lexAssertIs(RPARENT);
+    } else if (stringEquals(cycleTyTk.tokenTy, FORTK)) {
+        lexAssertIs(LPARENT);
+        parseAssert(parseIdentfication);
+        lexAssertIs(EQL);
+        parseAssert3(parseExpression);
+        lexAssertIs(SEMICN);
+        parseAssert(parseStatementIfCondition);
+        parseAssert(parseIdentfication);
+        lexAssertIs(EQL);
+        parseAssert(parseIdentfication);
+        parseAssert(parsePlus);
+        parseAssert(parseStatementForStep);
+        lexAssertIs(RPARENT);
+        parseAssert3(parseExpression);
+    } else {
+        lsp;
+        return false;
+    }
+    fprintf(output, "<循环语句>\n");
+    return true;
 }
 
 Bool parseStatementForStep(LexState *state, FILE *output) {
-    
+    if (!parseUnsignedNumber(state, output)) {
+        return false;
+    }
+    fprintf(output, "<步长>\n");
+    return true;
 }
 
 Bool parseStatementFuncCallWithResult(LexState *state, FILE *output) {
-    
+    lgp;
+    parseFallback(parseIdentfication);
+    lexFallback(LPARENT);
+    parseAssert(parseArgumentTable);
+    lexAssertIs(RPARENT);
+    fprintf(output, "<有返回值函数调用语句>\n");
+    return true;
 }
 
 Bool parseStatementFuncCallWithoutResult(LexState *state, FILE *output) {
-    
+    lgp;
+    parseFallback(parseIdentfication);
+    lexFallback(LPARENT);
+    parseAssert(parseArgumentTable);
+    lexAssertIs(RPARENT);
+    fprintf(output, "<有返回值函数调用语句>\n");
+    return true;
 }
 
 Bool parseStatementFuncCallArgumentList(LexState *state, FILE *output) {
-    
+    Bool nextMustHasVal = false;
+    while (true) {
+        if (!parseExpression(state, output, true)) {
+            if (nextMustHasVal) {
+                printf("Error: after , need expression");
+                exit(-1);
+            }
+            break;
+        }
+        if (lexGetIs(COMMA)) {
+            nextMustHasVal = true;
+        }
+    }
+    fprintf(output, "<值参数表>\n");
+    return true;
 }
 
 Bool parseStatementList(LexState *state, FILE *output) {
-    
+    while (true) {
+        if (!parseStatement(state, output)) {
+            break;
+        }
+    }
+    fprintf(output, "<语句列>\n");
+    return true;
 }
 
 Bool parseStatementFuncCallRead(LexState *state, FILE *output) {
-    
+    lgp;
+    lexFallback(SCANFTK);
+    lexFallback(LPARENT);
+    parseAssert(parseIdentfication);
+    while (true) {
+        if (!lexPeekIs(COMMA)) {
+            break;
+        }
+        lexGetToken(state);
+        parseAssert(parseIdentfication);
+    }
+    fprintf(output, "<读语句>\n");
+    return true;
 }
 
 Bool parseStatementFuncCallWrite(LexState *state, FILE *output) {
-    
+    lgp;
+    lexFallback(SCANFTK);
+    lexFallback(LPARENT);
+    parseAssert(parseIdentfication);
+    while (true) {
+        if (!lexPeekIs(COMMA)) {
+            break;
+        }
+        lexGetToken(state);
+        parseAssert(parseIdentfication);
+    }
+    fprintf(output, "<写语句>\n");
+    return true;
 }
 
 Bool parseStatementReturn(LexState *state, FILE *output) {
-    
+    lgp;
+    lexFallback(RETURNTK);
+    if (lexPeekIs(LPARENT)) {
+        lexGetToken(state);
+        parseAssert3(parseExpression);
+        lexAssertIs(RPARENT);
+    }
+    fprintf(output, "<返回语句>\n");
+    return true;
 }
 
 int main(int argc, const char * argv[]) {
@@ -808,7 +1308,7 @@ int main(int argc, const char * argv[]) {
     lexInit(&lex, "testfile.txt");
     FILE *wp = fopen("output.txt", "w+");
     
-    
+    parseProgram(&lex, wp);
     
     return 0;
 }