|
@@ -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;
|
|
|
}
|