From ffda3e942f7a41a9ac348cfe60ae27e211545ba3 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sun, 9 Oct 2016 12:16:14 +0300 Subject: [PATCH] started the parser --- src/mparser.cc | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/mparser.h | 8 +++ 2 files changed, 199 insertions(+) create mode 100644 src/mparser.cc create mode 100644 src/mparser.h diff --git a/src/mparser.cc b/src/mparser.cc new file mode 100644 index 0000000..b39df1a --- /dev/null +++ b/src/mparser.cc @@ -0,0 +1,191 @@ +#include +#include "mparser.h" +#include "machine.h" + +enum ASTNodeType { + AST_MACHINE, + AST_GEAR, + AST_STATEMENT, + AST_IDENT, + AST_NUMBER, + AST_VECTOR, + AST_FCALL +}; + +struct ASTNode { + std::vector children; +}; + +struct ParserState { + FILE *fp; + const char *fname; + Machine *mcn; + + int nextc; + int savedc; + + bool error; +}; + +static bool machine(ParserState *ps); +static bool expect(ParserState *ps, char c); +static bool expect_alpha(ParserState *ps); +static bool expect_digit(ParserState *ps); +static bool expect_alnum(ParserState *ps); +static bool match_str(ParserState *ps, const char *str); +static bool match_char(ParserState *ps, char c); +static bool mstatement(ParserState *ps); +static bool ident(ParserState *ps, std::string *s); +static bool gear(ParserState *ps); +static bool expression(ParserState *ps); + +static bool nextchar(ParserState *ps); +static void putback(ParserState *ps, char c); + +bool parse_machine(Machine *mcn, const char *fname) +{ + FILE *fp = fopen(fname, "rb"); + if(!fp) return false; + + ParserState pstate; + pstate.fname = fname; + pstate.fp = fp; + pstate.mcn = mcn; + pstate.savedc = -1; + pstate.nextc = fgetc(fp); // prime the parser + pstate.error = false; + + bool res = machine(&pstate); + fclose(fp); + return res; +} + +static bool machine(ParserState *ps) +{ + matchstr(ps, "machine"); + expect(ps, '{'); + + while(mstatement(ps)); + + expect(ps, '}'); + return true; +} + +static bool expect(ParserState *ps, int c) +{ + if(c != ps->nextc) { + ps->error = true; + return false; + } + nextchar(ps); + return true; +} + +static bool expect_alpha(ParserState *ps) +{ + if(!isalpha(ps->nextc)) { + ps->error = true; + return false; + } + nextchar(ps); + return true; +} + +static bool expect_digit(ParserState *ps) +{ + if(!isdigit(ps->nextc)) { + ps->error = true; + return false; + } + nextchar(ps); + return true; +} + +static bool expect_alnum(ParserState *ps) +{ + if(!isalnum(ps->nextc)) { + ps->error = true; + return false; + } + nextchar(ps); + return true; +} + +static bool match_str(ParserState *ps, const char *str) +{ + while(*str && match_char(ps, *str++)); + return !feof(ps->fp); +} + +static bool match_char(ParserState *ps, int c) +{ + if(ps->nextc != c) { + return false; + } + nextchar(ps); + return true; +} + +static bool expression(ParserState *ps); + +#define CHECK(x) if(!(x)) return false + +static bool mstatement(ParserState *ps) +{ + std::string id; + + CHECK(ident(ps, &id)); + if(id == "gear") { + gear(ps); + } else { + expect(ps, '='); + expression(ps); + } +} + +static bool expression(ParserState *ps) +{ +} + +static bool ident(ParserState *ps, std::string *s) +{ + CHECK(expect_alpha(ps)); + while(isalnum(ps->nextc) || ps->nextc == '_') { + s->append((char)ps->nextc); + CHECK(nextchar(ps)); + } + return true; +} + +static bool skip_line(FILE *fp) +{ + int c; + while((c = fgetc(fp)) != -1 && c != '\n'); + return c != -1; +} + +static bool nextchar(ParserState *ps) +{ + if(ps->savedc != -1) { + ps->nextc = ps->savedc; + ps->savedc = -1; + return true; + } + + while((ps->nextc = fgetc(ps->fp)) != -1) { + if(ps->nextc == '#') { + CHECK(skip_line(ps->fp)); + } + if(!isspace(ps->nextc)) { + break; + } + } + + return ps->nextc != -1; +} + +static void putback(ParserState *ps, char c) +{ + ps->savedc = ps->nextc; + ps->nextc = c; +} diff --git a/src/mparser.h b/src/mparser.h new file mode 100644 index 0000000..7fa1b6f --- /dev/null +++ b/src/mparser.h @@ -0,0 +1,8 @@ +#ifndef MPARSER_H_ +#define MPARSER_H_ + +#include + +int parse_machine(Machine *mcn, const char *fname); + +#endif /* MPARSER_H_ */ -- 1.7.10.4