From 2b94dc1d898a17ff30594c2e183c2b8234387f88 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Mon, 9 Apr 2012 19:00:13 -0400 Subject: [PATCH] More parsing & parse tree --- gmqcc | Bin 19062 -> 22074 bytes gmqcc.h | 16 ++-- lex.c | 5 +- main.c | 8 +- parse.c | 242 +++++++++++++++++++++++++++++++++++++++++++++++++------- 5 files changed, 234 insertions(+), 37 deletions(-) diff --git a/gmqcc b/gmqcc index 9bc7f27d9ed45849c15d18a76d331f73c6eaa88e..d00f3c7c3d36e9d63116895ef8972befc6e20940 100755 GIT binary patch literal 22074 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 diff --git a/gmqcc.h b/gmqcc.h index 7fda6fd..bd1d715 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -157,12 +157,11 @@ struct lex_file { #define TOKEN_GOTO 7 #define TOKEN_FOR 8 // extension #define TOKEN_INT 9 // extension -#define TOKEN_BOOL 10 // extension -#define TOKEN_VOID 11 -#define TOKEN_STRING 12 -#define TOKEN_FLOAT 13 -#define TOKEN_VECTOR 14 -#define TOKEN_ENTITY 15 +#define TOKEN_VOID 10 +#define TOKEN_STRING 11 +#define TOKEN_FLOAT 12 +#define TOKEN_VECTOR 13 +#define TOKEN_ENTITY 14 /* * Lexer state constants, these are numbers for where exactly in @@ -190,6 +189,11 @@ int error(int, const char *, ...); /* parse.c */ int parse(struct lex_file *); +struct parsenode { + struct parsenode *next; + int type; /* some token */ +}; + /* cpp.c */ int cpp (struct lex_file *); diff --git a/lex.c b/lex.c index 5333171..62067bb 100644 --- a/lex.c +++ b/lex.c @@ -27,6 +27,10 @@ #include #include "gmqcc.h" +/* + * Keywords are multichar, punctuation lexing is a bit more complicated + * than keyword lexing. + */ static const char *const lex_keywords[] = { "do", "else", "if", "while", "break", "continue", "return", "goto", @@ -34,7 +38,6 @@ static const char *const lex_keywords[] = { /* types */ "int", - "bool", "void", "string", "float", diff --git a/main.c b/main.c index 5134e98..bb5b83e 100644 --- a/main.c +++ b/main.c @@ -34,10 +34,11 @@ int main(int argc, char **argv) { const char *ofile = NULL; const char *ifile = NULL; int i; - if (argc <= 2) + if (argc <= 2) { return usage(*argv); + } - for (i=0; i +#include #include "gmqcc.h" +/* + * These are not lexical tokens: These are parse tree types. Most people + * perform tokenizing on language punctuation which is wrong. That stuff + * is technically already tokenized, it just needs to be parsed into a tree + */ +#define PARSE_TYPE_DO 0 +#define PARSE_TYPE_ELSE 1 +#define PARSE_TYPE_IF 2 +#define PARSE_TYPE_WHILE 3 +#define PARSE_TYPE_BREAK 4 +#define PARSE_TYPE_CONTINUE 5 +#define PARSE_TYPE_RETURN 6 +#define PARSE_TYPE_GOTO 7 +#define PARSE_TYPE_FOR 8 // extension +#define PARSE_TYPE_INT 9 // extension +#define PARSE_TYPE_BOOL 10 // extension +#define PARSE_TYPE_VOID 11 +#define PARSE_TYPE_STRING 12 +#define PARSE_TYPE_FLOAT 13 +#define PARSE_TYPE_VECTOR 14 +#define PARSE_TYPE_ENTITY 15 +#define PARSE_TYPE_LAND 16 +#define PARSE_TYPE_LOR 17 +#define PARSE_TYPE_LTEQ 18 +#define PARSE_TYPE_GTEQ 19 +#define PARSE_TYPE_EQEQ 20 +#define PARSE_TYPE_LNEQ 21 +#define PARSE_TYPE_COMMA 22 +#define PARSE_TYPE_LNOT 23 +#define PARSE_TYPE_STAR 24 +#define PARSE_TYPE_DIVIDE 25 +#define PARSE_TYPE_LPARTH 26 +#define PARSE_TYPE_RPARTH 27 +#define PARSE_TYPE_MINUS 28 +#define PARSE_TYPE_ADD 29 +#define PARSE_TYPE_EQUAL 30 +#define PARSE_TYPE_LSS 31 // left subscript +#define PARSE_TYPE_RSS 32 +#define PARSE_TYPE_LBS 33 // left bracket scope +#define PARSE_TYPE_RBS 34 // right bracket scope +#define PARSE_TYPE_ELIP 35 // ... +#define PARSE_TYPE_DOT 36 +#define PARSE_TYPE_LT 37 +#define PARSE_TYPE_GT 38 +#define PARSE_TYPE_BAND 39 +#define PARSE_TYPE_BOR 40 +#define PARSE_TYPE_DONE 41 // finished statement + +/* + * Adds a parse type to the parse tree, this is where all the hard + * work actually begins. + */ +#define PARSE_TREE_ADD(X) \ + do { \ + parsetree->next = mem_a(sizeof(struct parsenode)); \ + parsetree->next->next = NULL; \ + parsetree->next->type = (X); \ + parsetree = parsetree->next; \ + } while (0) static const char *const parse_punct[] = { "&&", "||", "<=", ">=", "==", "!=", ";", ",", "!", "*", - "/" , "(" , "-" , "+" , "=" , "[" , "]", "{", "}", "...", - "." , "<" , ">" , "#" , "&" , "|" , "$", "@", ":", NULL - /* - * $,@,: are extensions: - * $ is a shorter `self`, so instead of self.frags, $.frags - * @ is a constructor - * : is compiler builtin functions - */ + "/" , "(" , ")" , "-" , "+" , "=" , "[" , "]", "{", "}", "...", + "." , "<" , ">" , "&" , "|" , NULL }; +#define STORE(X) { \ + printf(X); \ + break; \ +} + +void parse_debug(struct parsenode *tree) { + while (tree && tree->next != NULL) { + /* skip blanks */ + if (tree->type == 0) { + tree = tree->next; + continue; + } + + switch (tree->type) { + case PARSE_TYPE_ADD: STORE("ADD \n"); + case PARSE_TYPE_BAND: STORE("BITAND \n"); + case PARSE_TYPE_BOR: STORE("BITOR \n"); + case PARSE_TYPE_BREAK: STORE("BREAK \n"); + case PARSE_TYPE_COMMA: STORE("SEPERATOR\n"); + case PARSE_TYPE_CONTINUE: STORE("CONTINUE\n"); + case PARSE_TYPE_DIVIDE: STORE("DIVIDE\n"); + case PARSE_TYPE_EQUAL: STORE("ASSIGNMENT\n"); + case PARSE_TYPE_GOTO: STORE("GOTO\n"); + case PARSE_TYPE_DOT: STORE("DOT\n"); + + + case PARSE_TYPE_ELIP: STORE("DECLTYPE: VALIST\n"); + case PARSE_TYPE_ENTITY: STORE("DECLTYPE: ENTITY\n"); + case PARSE_TYPE_INT: STORE("DECLTYPE: INT\n"); + case PARSE_TYPE_FLOAT: STORE("DECLTYPE: FLOAT\n"); + case PARSE_TYPE_BOOL: STORE("DECLTYPE: BOOL\n"); + + case PARSE_TYPE_GT: STORE("TEST: GREATER THAN\n"); + case PARSE_TYPE_LT: STORE("TEST: LESS THAN\n"); + case PARSE_TYPE_GTEQ: STORE("TEST: GREATER THAN OR EQUAL\n"); + case PARSE_TYPE_LTEQ: STORE("TEST: LESS THAN OR EQUAL\n"); + case PARSE_TYPE_LNEQ: STORE("TEST: NOT EQUAL\n"); + case PARSE_TYPE_EQEQ: STORE("TEST: EQUAL-EQUAL\n"); + + case PARSE_TYPE_LBS: break; + case PARSE_TYPE_RBS: break; + + case PARSE_TYPE_LAND: STORE("LOGICAL: AND\n"); + case PARSE_TYPE_LNOT: STORE("LOGICAL: NOT\n"); + case PARSE_TYPE_LOR: STORE("LOGICAL: OR\n"); + case PARSE_TYPE_LPARTH: STORE("PARTH: END\n"); + case PARSE_TYPE_RPARTH: STORE("PARTH: BEG\n"); + + case PARSE_TYPE_FOR: STORE("LOOP: FOR\n"); + case PARSE_TYPE_DO: STORE("LOOP: DO\n"); + case PARSE_TYPE_ELSE: STORE("BLOCK: ELSE\n"); + case PARSE_TYPE_IF: STORE("BLOCK: IF\n"); + } + tree = tree->next; + } +} + +/* + * This just skips the token and throws it in the parse tree for later + * checking / optimization / codegen, it doesn't do anything with it + * like syntax check for legal use -- like it should as it's a TODO item + * which is not implemented + */ +#define PARSE_TODO(X) { \ + token = lex_token(file); \ + PARSE_TREE_ADD(X); \ + break; \ +} + int parse(struct lex_file *file) { + struct parsenode *parsetree = NULL; + struct parsenode *parseroot = NULL; + + /* + * Allocate memory for our parse tree: + * the parse tree is just a singly linked list which will contain + * all the data for code generation. + */ + if (!parseroot) { + parseroot = mem_a(sizeof(struct parsenode)); + if (!parseroot) + return error(ERROR_INTERNAL, "Ran out of memory", " "); + parsetree = parseroot; + parsetree = parseroot; + } + int token = 0; while ((token = lex_token(file)) != ERROR_LEX && \ token != ERROR_COMPILER && \ @@ -51,7 +190,36 @@ int parse(struct lex_file *file) { if (token != '(') error(ERROR_PARSE, "Expected `(` after if\n", ""); + + PARSE_TREE_ADD(PARSE_TYPE_IF); + break; + case TOKEN_ELSE: + token = lex_token(file); + while ((token == ' ' || token == '\n') && file->length >= 0) + token = lex_token(file); + + PARSE_TREE_ADD(PARSE_TYPE_ELSE); break; + case TOKEN_FOR: + token = lex_token(file); + while ((token == ' ' || token == '\n') && file->length >= 0) + token = lex_token(file); + + PARSE_TREE_ADD(PARSE_TYPE_FOR); + break; + + case TOKEN_DO: PARSE_TODO(PARSE_TYPE_DO); + case TOKEN_WHILE: PARSE_TODO(PARSE_TYPE_WHILE); + case TOKEN_BREAK: PARSE_TODO(PARSE_TYPE_BREAK); + case TOKEN_CONTINUE: PARSE_TODO(PARSE_TYPE_CONTINUE); + case TOKEN_RETURN: PARSE_TODO(PARSE_TYPE_RETURN); + case TOKEN_GOTO: PARSE_TODO(PARSE_TYPE_GOTO); + case TOKEN_INT: PARSE_TODO(PARSE_TYPE_INT); + case TOKEN_VOID: PARSE_TODO(PARSE_TYPE_VOID); + case TOKEN_STRING: PARSE_TODO(PARSE_TYPE_STRING); + case TOKEN_FLOAT: PARSE_TODO(PARSE_TYPE_FLOAT); + case TOKEN_VECTOR: PARSE_TODO(PARSE_TYPE_VECTOR); + case TOKEN_ENTITY: PARSE_TODO(PARSE_TYPE_ENTITY); /* TODO: Preprocessor */ case '#': @@ -63,81 +231,101 @@ int parse(struct lex_file *file) { token = lex_token(file); break; - /* PUNCTUATION PARSING BEGINS */ + /* + * From here down is all language punctuation: There is no + * need to actual create tokens from these because they're already + * tokenized as these individual tokens (which are in a special area + * of the ascii table which doesn't conflict with our other tokens + * which are higer than the ascii table. + */ case '&': /* & */ token = lex_token(file); if (token == '&') { /* && */ token = lex_token(file); - printf("--> LOGICAL AND\n"); + PARSE_TREE_ADD(PARSE_TYPE_LAND); goto end; } + PARSE_TREE_ADD(PARSE_TYPE_BAND); printf("--> BITWISE AND\n"); break; case '|': /* | */ token = lex_token(file); if (token == '|') { /* || */ token = lex_token(file); - printf("--> LOGICAL OR\n"); + PARSE_TREE_ADD(PARSE_TYPE_LOR); goto end; } - printf("--> BITWISE OR\n"); + PARSE_TREE_ADD(PARSE_TYPE_BOR); break; case '!': token = lex_token(file); if (token == '=') { /* != */ token = lex_token(file); - printf("--> LOGICAL NOT EQUAL\n"); + PARSE_TREE_ADD(PARSE_TYPE_LNEQ); goto end; } - printf("--> LOGICAL NOT\n"); + PARSE_TREE_ADD(PARSE_TYPE_LNOT); break; case '<': /* < */ token = lex_token(file); if (token == '=') { /* <= */ token = lex_token(file); - printf("--> LESS THAN OR EQUALL\n"); + PARSE_TREE_ADD(PARSE_TYPE_LTEQ); goto end; } - printf("--> LESS THAN\n"); + PARSE_TREE_ADD(PARSE_TYPE_LT); break; case '>': /* > */ token = lex_token(file); if (token == '=') { /* >= */ token = lex_token(file); - printf("--> GREATER THAN OR EQUAL\n"); + PARSE_TREE_ADD(PARSE_TYPE_GTEQ); goto end; } - printf("--> GREATER THAN\n"); + PARSE_TREE_ADD(PARSE_TYPE_GT); break; case '=': token = lex_token(file); if (token == '=') { /* == */ token = lex_token(file); - printf("--> COMPARISION \n"); + PARSE_TREE_ADD(PARSE_TYPE_EQEQ); goto end; } - printf("--> ASSIGNMENT\n"); + PARSE_TREE_ADD(PARSE_TYPE_EQUAL); break; case ';': token = lex_token(file); - printf("--> FINISHED STATMENT\n"); + PARSE_TREE_ADD(PARSE_TYPE_DONE); break; case '-': token = lex_token(file); - printf("--> SUBTRACTION EXPRESSION\n"); + PARSE_TREE_ADD(PARSE_TYPE_MINUS); break; case '+': token = lex_token(file); - printf("--> ASSIGNMENT EXPRRESSION\n"); + PARSE_TREE_ADD(PARSE_TYPE_ADD); + break; + case '(': + token = lex_token(file); + PARSE_TREE_ADD(PARSE_TYPE_LPARTH); + break; + case ')': + token = lex_token(file); + PARSE_TREE_ADD(PARSE_TYPE_RPARTH); + break; + case '{': + token = lex_token(file); + PARSE_TREE_ADD(PARSE_TYPE_LBS); + break; + case '}': + token = lex_token(file); + PARSE_TREE_ADD(PARSE_TYPE_RBS); break; } end:; } + parse_debug(parseroot); lex_reset(file); - // "&&", "||", "<=", ">=", "==", "!=", ";", ",", "!", "*", - //"/" , "(" , "-" , "+" , "=" , "[" , "]", "{", "}", "...", - //"." , "<" , ">" , "#" , "&" , "|" , "$", "@", ":", NULL - return 1; } -- 2.39.2