|
@@ -8,6 +8,7 @@
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
|
+#include <stdarg.h>
|
|
|
|
|
|
#define true 1
|
|
#define true 1
|
|
#define false 0
|
|
#define false 0
|
|
@@ -405,16 +406,409 @@ Token lexSTRCON(CachedFile *file, TokenRule rule) {
|
|
return tk;
|
|
return tk;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// MARK: - Lex Package
|
|
|
|
+
|
|
|
|
+typedef struct {
|
|
|
|
+ Token buf[1024];
|
|
|
|
+ int bufSize;
|
|
|
|
+ CachedFile *fp;
|
|
|
|
+} LexState;
|
|
|
|
+
|
|
|
|
+void lexInit(LexState *state, String filePath) {
|
|
|
|
+ state->fp = cached_fopen(filePath);
|
|
|
|
+ state->bufSize = 0;
|
|
|
|
+ memset(state->buf, 0, sizeof(state->buf));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Token lexGetToken(LexState *state) {
|
|
|
|
+ if (state->bufSize > 0) {
|
|
|
|
+ Token tk = state->buf[state->bufSize - 1];
|
|
|
|
+ state->bufSize--;
|
|
|
|
+ return tk;
|
|
|
|
+ }
|
|
|
|
+ return lexNext(state->fp);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void lexPutToken(LexState *state, Token token) {
|
|
|
|
+ state->buf[state->bufSize] = token;
|
|
|
|
+ state->bufSize++;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Token lexPeekToken(LexState *state) {
|
|
|
|
+ Token token = lexGetToken(state);
|
|
|
|
+ lexPutToken(state, token);
|
|
|
|
+ return token;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+typedef struct {
|
|
|
|
+ Token buf[1024];
|
|
|
|
+ int bufSize;
|
|
|
|
+ CachedFileFPos fpos;
|
|
|
|
+} LexStatePos;
|
|
|
|
+
|
|
|
|
+LexStatePos lexGetPos(LexState *state) {
|
|
|
|
+ LexStatePos pos;
|
|
|
|
+ memcpy(pos.buf, state->buf, sizeof(pos.buf));
|
|
|
|
+ pos.bufSize = state->bufSize;
|
|
|
|
+ cached_fgetpos(state->fp, &pos.fpos);
|
|
|
|
+ return pos;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void lexSetPos(LexState *state, LexStatePos *pos) {
|
|
|
|
+ cached_fsetpos(state->fp, &pos->fpos);
|
|
|
|
+ memcpy(state->buf, pos->buf, sizeof(state->buf));
|
|
|
|
+ state->bufSize = pos->bufSize;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// MARK: - Parser
|
|
|
|
+
|
|
|
|
+Bool parsePlus(LexState *state, FILE *output);
|
|
|
|
+Bool parseMult(LexState *state, FILE *output);
|
|
|
|
+Bool parseRelation(LexState *state, FILE *output);
|
|
|
|
+Bool parseLiterialNumber(LexState *state, FILE *output);
|
|
|
|
+Bool parseLiterialCHAR(LexState *state, FILE *output);
|
|
|
|
+Bool parseLiterialString(LexState *state, FILE *output);
|
|
|
|
+Bool parseProgram(LexState *state, FILE *output);
|
|
|
|
+Bool parseConstantDescription(LexState *state, FILE *output, Bool printIfIs);
|
|
|
|
+Bool parseConstantDefinition(LexState *state, FILE *output);
|
|
|
|
+Bool parseUnsignedNumber(LexState *state, FILE *output);
|
|
|
|
+Bool parseNumber(LexState *state, FILE *output);
|
|
|
|
+Bool parseIdentfication(LexState *state, FILE *output);
|
|
|
|
+Bool parseDeclaractionHead(LexState *state, FILE *output);
|
|
|
|
+Bool parseVariableDescription(LexState *state, FILE *output);
|
|
|
|
+Bool parseVariableDefinition(LexState *state, FILE *output);
|
|
|
|
+Bool parseTypeLabel(LexState *state, FILE *output);
|
|
|
|
+Bool parseReturnFunction(LexState *state, FILE *output);
|
|
|
|
+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 parseItem(LexState *state, FILE *output);
|
|
|
|
+Bool parseFactor(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatement(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatementAssign(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatementIf(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatementIfCondition(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatementCycle(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatementForStep(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatementFuncCallWithResult(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatementFuncCallWithoutResult(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatementFuncCallArgumentList(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatementList(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatementFuncCallRead(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatementFuncCallWrite(LexState *state, FILE *output);
|
|
|
|
+Bool parseStatementReturn(LexState *state, FILE *output);
|
|
|
|
+
|
|
|
|
+Bool parsePlus(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ Token tk = lexGetToken(state);
|
|
|
|
+ if (stringEquals(tk.tokenTy, PLUS) || stringEquals(tk.tokenTy, MINU)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseMult(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ Token tk = lexGetToken(state);
|
|
|
|
+ if (stringEquals(tk.tokenTy, MULT) || stringEquals(tk.tokenTy, DIV)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseRelation(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ Token tk = lexGetToken(state);
|
|
|
|
+ if (stringEquals(tk.tokenTy, LEQ) || stringEquals(tk.tokenTy, LSS) ||
|
|
|
|
+ stringEquals(tk.tokenTy, GEQ) || stringEquals(tk.tokenTy, GRE) ||
|
|
|
|
+ stringEquals(tk.tokenTy, EQL) || stringEquals(tk.tokenTy, NEQ)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseLiterialNumber(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ Token tk = lexGetToken(state);
|
|
|
|
+ if (stringEquals(tk.tokenTy, INTCON)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseLiterialCHAR(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ Token tk = lexGetToken(state);
|
|
|
|
+ if (stringEquals(tk.tokenTy, CHARCON)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseLiterialString(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ Token tk = lexGetToken(state);
|
|
|
|
+ if (!stringEquals(tk.tokenTy, STRCON)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ fprintf(output, "<字符串>\n");
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseProgram(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseConstantDescription(LexState *state, FILE *output, Bool printIfIs) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ Token tk = lexGetToken(state);
|
|
|
|
+ if (!stringEquals(tk.tokenTy, CONSTTK)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (!parseConstantDefinition(state, output)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ Token semicnTk = lexGetToken(state);
|
|
|
|
+ if (!stringEquals(semicnTk.tokenTy, SEMICN)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ parseConstantDescription(state, output, false);
|
|
|
|
+ if (printIfIs) {
|
|
|
|
+ fprintf(output, "<常量说明>\n");
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseConstantDefinitionExcludeType(LexState *state, Token tokTy, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ if (!parseIdentfication(state, output)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ Token tokEqual = lexGetToken(state);
|
|
|
|
+ if (!stringEquals(tokEqual.tokenTy, EQL)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (stringEquals(tokTy.tokenTy, INTTK)) {
|
|
|
|
+ if (!parseNumber(state, output)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (stringEquals(tokTy.tokenTy, CHARTK)) {
|
|
|
|
+ if (!parseLiterialCHAR(state, output)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseConstantDefinition(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ Token tokTy = lexGetToken(state);
|
|
|
|
+ if (!(stringEquals(tokTy.tokenTy, INTTK) || stringEquals(tokTy.tokenTy, CHARTK))) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (!parseConstantDefinitionExcludeType(state, tokTy, output)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ Token tokTest = lexGetToken(state);
|
|
|
|
+ if (!stringEquals(tokTest.tokenTy, COMMA)) {
|
|
|
|
+ lexPutToken(state, tokTest);
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ if (!parseConstantDefinitionExcludeType(state, tokTy, output)) {
|
|
|
|
+ printf("Error: Expect , <Identification> = <Object>");
|
|
|
|
+ exit(-1);
|
|
|
|
+ }
|
|
|
|
+ fprintf(output, "<常量定义>\n");
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseUnsignedNumber(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ Token tk = lexGetToken(state);
|
|
|
|
+ if (!stringEquals(tk.tokenTy, INTCON)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ fprintf(output, "<无符号整数>\n");
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseNumber(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ if (!parsePlus(state, output)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (!parseUnsignedNumber(state, output)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ fprintf(output, "<整数>\n");
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseIdentfication(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ Token tk = lexGetToken(state);
|
|
|
|
+ if (stringEquals(tk.tokenTy, IDENFR)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseDeclaractionHead(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ Token tk = lexGetToken(state);
|
|
|
|
+ if (!(stringEquals(tk.tokenTy, INTTK) || stringEquals(tk.tokenTy, CHARTK))) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (!parseIdentfication(state, output)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ fprintf(output, "<声明头部>\n");
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseVariableDescription(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ if (!parseVariableDefinition(state, output)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ Token tok = lexGetToken(state);
|
|
|
|
+ if (!stringEquals(tok.tokenTy, SEMICN)) {
|
|
|
|
+ lexSetPos(state, &lp);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ parseVariableDescription(state, output);
|
|
|
|
+ fprintf(output, "<变量说明>\n");
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseVariableDefinition(LexState *state, FILE *output) {
|
|
|
|
+ LexStatePos lp = lexGetPos(state);
|
|
|
|
+ if (!parseTypeLabel(state, output)) {
|
|
|
|
+ if type
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseTypeLabel(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseReturnFunction(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+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 parseItem(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseFactor(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatement(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatementAssign(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatementIf(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatementIfCondition(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatementCycle(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatementForStep(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatementFuncCallWithResult(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatementFuncCallWithoutResult(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatementFuncCallArgumentList(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatementList(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatementFuncCallRead(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatementFuncCallWrite(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Bool parseStatementReturn(LexState *state, FILE *output) {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
int main(int argc, const char * argv[]) {
|
|
int main(int argc, const char * argv[]) {
|
|
doInitialization();
|
|
doInitialization();
|
|
- CachedFile *fp = cached_fopen("testfile.txt");
|
|
|
|
|
|
+ LexState lex;
|
|
|
|
+ lexInit(&lex, "testfile.txt");
|
|
FILE *wp = fopen("output.txt", "w+");
|
|
FILE *wp = fopen("output.txt", "w+");
|
|
- Token currentWord;
|
|
|
|
- while (!(currentWord = lexNext(fp)).isEmpty) {
|
|
|
|
- if (stringEquals(currentWord.tokenTy, EOFTK)) {
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- fprintf(wp, "%s %s\n", currentWord.tokenTy, currentWord.tokenBody);
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|