From 35773a9e1586f2e6565fbfa4e7d296a709006887 Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Wed, 11 Oct 2023 23:47:30 -0400 Subject: [PATCH] WIP --- Makefile | 17 ++- bminor.c | 93 +++++++-------- grammar.y | 244 +++++++++++++++++++++++++++++++++++++++ lex.yy.l | 130 +++++++++++---------- parser.c | 19 +++ parser.h | 1 + runtest.sh | 3 + scanner.c | 4 +- test/parser/bad0.bminor | 1 + test/parser/bad1.bminor | 1 + test/parser/bad2.bminor | 1 + test/parser/bad3.bminor | 2 + test/parser/good0.bminor | 2 + test/parser/good1.bminor | 3 + test/parser/good2.bminor | 3 + test/parser/good3.bminor | 9 ++ test/parser/good4.bminor | 11 ++ test/parser/good5.bminor | 6 + test/parser/good6.bminor | 10 ++ token.h | 65 ----------- 20 files changed, 443 insertions(+), 182 deletions(-) create mode 100644 grammar.y create mode 100644 parser.c create mode 100644 parser.h create mode 100644 test/parser/bad0.bminor create mode 100644 test/parser/bad1.bminor create mode 100644 test/parser/bad2.bminor create mode 100644 test/parser/bad3.bminor create mode 100644 test/parser/good0.bminor create mode 100644 test/parser/good1.bminor create mode 100644 test/parser/good2.bminor create mode 100644 test/parser/good3.bminor create mode 100644 test/parser/good4.bminor create mode 100644 test/parser/good5.bminor create mode 100644 test/parser/good6.bminor delete mode 100644 token.h diff --git a/Makefile b/Makefile index 3f57f89..26b2ec4 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -bminor: bminor.c encoder.o scanner.o lex.yy.o +bminor: bminor.c encoder.o scanner.o lex.yy.o parser.o grammar.tab.o gcc $^ -o $@ encoder.o: encoder.c @@ -10,7 +10,16 @@ lex.yy.c: lex.yy.l lex.yy.o: lex.yy.c gcc -c $^ -o $@ -scanner.o: scanner.c +scanner.o: scanner.c token.h + gcc -c $< -o $@ + +parser.o: parser.c + gcc -c $^ -o $@ + +grammar.tab.c token.h: grammar.y lex.yy.c + bison -v --defines=token.h $< + +grammar.tab.o: grammar.tab.c gcc -c $^ -o $@ # Tests @@ -20,8 +29,12 @@ test-encoder: test-scanner: ./runtest.sh scanner +test-parser: + ./runtest.sh parser + clean: rm -f lex.yy.c + rm -f token.h grammar.tab.c grammar.output rm -f *.o rm -f ./test/*/*.bminor.out rm -f bminor \ No newline at end of file diff --git a/bminor.c b/bminor.c index 33cb94e..dc82e0b 100644 --- a/bminor.c +++ b/bminor.c @@ -4,6 +4,7 @@ #include "encoder.h" #include "scanner.h" +#include "parser.h" void usage(int exit_code) { @@ -13,61 +14,49 @@ void usage(int exit_code) int main(int argc, char* argv[]) { + char* option, * filename; - if (argc == 1) - usage(1); + switch (argc) + { + case 1: + usage(EXIT_FAILURE); + break; + case 2: + if (strcmp(argv[1], "--help") == 0) + usage(EXIT_SUCCESS); + else usage(EXIT_FAILURE); + break; + case 3: + option = argv[1]; + filename = argv[2]; + break; + default: + fprintf(stderr, "Too many arguments.\n"); + usage(EXIT_FAILURE); + break; + } - for (int i = 1; i < argc; i++) + if (strcmp(option, "--encode") == 0) + { + if (decode(filename) == 0) + return EXIT_SUCCESS; + } + else if (strcmp(option, "--scan") == 0) + { + if (scan(filename) == 0) + return EXIT_SUCCESS; + } + else if (strcmp(option, "--parse") == 0) + { + if (parse(filename) == 0) + return EXIT_SUCCESS; + } + else { - if (argv[i][0] == '-') - { - if (strcmp(argv[i], "--help") == 0) - usage(0); - else if (strcmp(argv[i], "--encode") == 0) - { - const char* filename = argv[++i]; - if (filename) - { - if (decode(filename) == 0) - return EXIT_SUCCESS; - else - { - fprintf(stderr, "Failed to decode file %s\n", filename); - return EXIT_FAILURE; - } - } - else - { - fprintf(stderr, "Missing filename to be encoded\n"); - return EXIT_FAILURE; - } - } - else if (strcmp(argv[i], "--scan") == 0) - { - const char* filename = argv[++i]; - if (filename) - { - if (scan(filename) == 0) - return EXIT_SUCCESS; - else - { - fprintf(stderr, "Failed to scan file %s\n", filename); - return EXIT_FAILURE; - } - } - else - { - fprintf(stderr, "Missing filename to be scanned\n"); - return EXIT_FAILURE; - } - } - else - { - fprintf(stderr, "Unknown option '%s'\n", argv[i]); - usage(1); - } - } + fprintf(stderr, "Unknown option '%s'\n", option); + usage(EXIT_FAILURE); } - return EXIT_SUCCESS; + fprintf(stderr, "Failed to %s file %s\n", option + 2, filename); + return EXIT_FAILURE; } diff --git a/grammar.y b/grammar.y new file mode 100644 index 0000000..e0fa481 --- /dev/null +++ b/grammar.y @@ -0,0 +1,244 @@ +%{ +#include +#define YYDEBUG 1 + +extern int yylex(); +extern int yylineno; +extern char *yytext; + +void yyerror(const char *s) { + fprintf(stderr, "Error: %s at line %d near '%s'\n", s, yylineno, yytext); +} +%} + +/* Keywords */ +%token TOKEN_ARRAY +%token TOKEN_AUTO +%token TOKEN_BOOLEAN +%token TOKEN_CHAR +%token TOKEN_ELSE +%token TOKEN_FALSE +%token TOKEN_FLOAT +%token TOKEN_FOR +%token TOKEN_FUNCTION +%token TOKEN_IF +%token TOKEN_INTEGER +%token TOKEN_PRINT +%token TOKEN_RETURN +%token TOKEN_STRING +%token TOKEN_TRUE +%token TOKEN_VOID +%token TOKEN_WHILE + +/* Operators */ +%token TOKEN_INCREMENT +%token TOKEN_DECREMENT +%token TOKEN_EXPONENT +%token TOKEN_MULTIPLY +%token TOKEN_DIVIDE +%token TOKEN_MODULO +%token TOKEN_ADD +%token TOKEN_MINUS +%token TOKEN_LESS +%token TOKEN_LESS_OR_EQUAL +%token TOKEN_GREATER +%token TOKEN_GREATER_OR_EQUAL +%token TOKEN_EQUAL +%token TOKEN_NOT_EQUAL +%token TOKEN_LOGICAL_AND +%token TOKEN_LOGICAL_OR +%token TOKEN_LOGICAL_NOT +%token TOKEN_ASSIGN + +/* Symbols */ +%token TOKEN_LPAREN +%token TOKEN_RPAREN +%token TOKEN_LBRACKET +%token TOKEN_RBRACKET +%token TOKEN_LBRACE +%token TOKEN_RBRACE +%token TOKEN_SEMICOLON +%token TOKEN_COLON +%token TOKEN_COMMA + +/* Identifiers and Literals */ +%token TOKEN_ID +%token TOKEN_INT_LITERAL +%token TOKEN_FLOAT_LITERAL +%token TOKEN_CHAR_LITERAL +%token TOKEN_STRING_LITERAL + +/* Error */ +%token TOKEN_EOF +%token TOKEN_ERROR + +%% +prog : decl_list TOKEN_EOF + ; + +/* Declarations */ + +decl_list : /* epsilon */ + | decl_list decl + ; + +decl : param TOKEN_SEMICOLON + | param TOKEN_ASSIGN init + ; + +init : expr TOKEN_SEMICOLON + | TOKEN_LBRACE opt_stmt_list TOKEN_RBRACE /* function body */ + | TOKEN_LBRACE expr_list TOKEN_RBRACE /* array */ + ; + +/* Statements */ + +opt_stmt_list : /* epsilon */ + | stmt_list + ; + +stmt_list : stmt + | stmt_list stmt + ; + +stmt : TOKEN_LBRACE stmt_list TOKEN_RBRACE + | for_loop + | if_cond + | print_stmt + | return_stmt + | decl + | expr TOKEN_SEMICOLON + ; + +for_loop : TOKEN_FOR TOKEN_LPAREN + opt_expr TOKEN_SEMICOLON opt_expr TOKEN_SEMICOLON opt_expr + TOKEN_RPAREN stmt + ; + +if_cond : TOKEN_IF TOKEN_LPAREN opt_expr TOKEN_RPAREN else_stmt + ; + +else_stmt : TOKEN_ELSE stmt + | /* epsilon */ + ; + +print_stmt : TOKEN_PRINT opt_expr_list TOKEN_SEMICOLON + ; + +return_stmt : TOKEN_RETURN opt_expr TOKEN_SEMICOLON + ; + +/* Expressions */ + +opt_expr_list : /* epsilon */ + | expr_list + ; + +expr_list : expr + | expr_list TOKEN_COMMA expr + ; + +opt_expr : /* epsilon */ + | expr + ; + +expr : expr1 + ; + +expr1 : lval TOKEN_ASSIGN expr1 + | expr2 + ; + +lval : TOKEN_ID + | TOKEN_ID index + ; + +expr2 : expr2 TOKEN_LOGICAL_OR expr3 + | expr3 + ; + +expr3 : expr3 TOKEN_LOGICAL_AND expr4 + | expr4 + ; + +expr4 : expr4 TOKEN_EQUAL expr5 + | expr4 TOKEN_NOT_EQUAL expr5 + | expr4 TOKEN_LESS expr5 + | expr4 TOKEN_LESS_OR_EQUAL expr5 + | expr4 TOKEN_GREATER expr5 + | expr4 TOKEN_GREATER_OR_EQUAL expr5 + | expr5 + ; + +expr5 : expr5 TOKEN_ADD expr6 + | expr5 TOKEN_MINUS expr6 + | expr6 + ; + +expr6 : expr6 TOKEN_MULTIPLY expr7 + | expr6 TOKEN_DIVIDE expr7 + | expr6 TOKEN_MODULO expr7 + | expr7 + ; + +expr7 : expr7 TOKEN_EXPONENT expr8 + | expr8 + ; + +expr8 : TOKEN_MINUS expr8 + | TOKEN_LOGICAL_NOT expr8 + | expr9 + ; + +expr9 : expr9 TOKEN_INCREMENT + | expr9 TOKEN_DECREMENT + | group + ; + +group : TOKEN_LPAREN expr TOKEN_RPAREN + | TOKEN_ID TOKEN_LPAREN opt_expr_list TOKEN_RPAREN + | TOKEN_ID index + | factor + ; + +index : TOKEN_LBRACKET expr TOKEN_RBRACKET + ; + +factor : TOKEN_ID + | TOKEN_INT_LITERAL + | TOKEN_FLOAT_LITERAL + | TOKEN_CHAR_LITERAL + | TOKEN_STRING_LITERAL + | TOKEN_TRUE + | TOKEN_FALSE + ; + +/* Types */ + +type : TOKEN_INTEGER + | TOKEN_FLOAT + | TOKEN_BOOLEAN + | TOKEN_CHAR + | TOKEN_STRING + | TOKEN_VOID + | TOKEN_ARRAY index type + | type_func + ; + +type_func : TOKEN_FUNCTION type TOKEN_LPAREN opt_param_list TOKEN_RPAREN + ; + +opt_param_list : /* epsilon */ + | param_list + ; + +param_list : param + | param_list TOKEN_COMMA param + ; + +param : TOKEN_ID TOKEN_COLON type + ; + +%% + +// int yywrap() { return 0; } \ No newline at end of file diff --git a/lex.yy.l b/lex.yy.l index 498efda..6a5f4fb 100644 --- a/lex.yy.l +++ b/lex.yy.l @@ -3,29 +3,31 @@ #include #include "token.h" #include "encoder.h" + +static int returned_eof = 0; %} %% /* Keywords */ -array { printf("ARRAY\n"); return T_ARRAY; } -auto { printf("AUTO\n"); return T_AUTO; } -boolean { printf("BOOLEAN\n"); return T_BOOLEAN; } -char { printf("CHAR\n"); return T_CHAR; } -else { printf("ELSE\n"); return T_ELSE; } -false { printf("FALSE\n"); return T_FALSE; } -float { printf("FLOAT\n"); return T_FLOAT; } -for { printf("FOR\n"); return T_FOR; } -function { printf("FUNCTION\n"); return T_FUNCTION; } -if { printf("IF\n"); return T_IF; } -integer { printf("INTEGER\n"); return T_INTEGER; } -print { printf("PRINT\n"); return T_PRINT; } -return { printf("RETURN\n"); return T_RETURN; } -string { printf("STRING\n"); return T_STRING; } -true { printf("TRUE\n"); return T_TRUE; } -print { printf("TRUE\n"); return T_TRUE; } -void { printf("VOID\n"); return T_VOID; } -while { printf("WHILE\n"); return T_WHILE; } +array { printf("ARRAY\n"); return TOKEN_ARRAY; } +auto { printf("AUTO\n"); return TOKEN_AUTO; } +boolean { printf("BOOLEAN\n"); return TOKEN_BOOLEAN; } +char { printf("CHAR\n"); return TOKEN_CHAR; } +else { printf("ELSE\n"); return TOKEN_ELSE; } +false { printf("FALSE\n"); return TOKEN_FALSE; } +float { printf("FLOAT\n"); return TOKEN_FLOAT; } +for { printf("FOR\n"); return TOKEN_FOR; } +function { printf("FUNCTION\n"); return TOKEN_FUNCTION; } +if { printf("IF\n"); return TOKEN_IF; } +integer { printf("INTEGER\n"); return TOKEN_INTEGER; } +print { printf("PRINT\n"); return TOKEN_PRINT; } +return { printf("RETURN\n"); return TOKEN_RETURN; } +string { printf("STRING\n"); return TOKEN_STRING; } +true { printf("TRUE\n"); return TOKEN_TRUE; } +print { printf("TRUE\n"); return TOKEN_TRUE; } +void { printf("VOID\n"); return TOKEN_VOID; } +while { printf("WHILE\n"); return TOKEN_WHILE; } /* Identifiers and Literals */ /* Literals have higher precedence to ensure preceding plus and minus @@ -33,24 +35,24 @@ while { printf("WHILE\n"); return T_WHILE; } [a-zA-Z_][a-zA-Z0-9_]* { printf("IDENTIFIER: %s\n", yytext); - return T_IDENTIFIER; + return TOKEN_ID; } -[+-]?([1-9][0-9]*|0) { +[1-9][0-9]*|0 { printf("INTEGER_LITERAL: %s\n", yytext); - return T_INTEGER_LITERAL; + return TOKEN_INT_LITERAL; } -[+-]?[0-9]*\.[0-9]+ { +[0-9]*\.[0-9]+ { /* Float without decimal point */ - printf("FLOAT_LITERAL: %s\n", yytext); - return T_FLOAT_LITERAL; + printf("TOKEN_FLOAT_LITERAL: %s\n", yytext); + return TOKEN_FLOAT_LITERAL; } -[+-]?[0-9]*(\.[0-9]+)?[eE][+-]?[1-9]+[0-9]* { +[0-9]*(\.[0-9]+)?[eE][+-]?[1-9]+[0-9]* { /* Float with scientific notation */ - printf("FLOAT_LITERAL: %s\n", yytext); - return T_FLOAT_LITERAL; + printf("TOKEN_FLOAT_LITERAL: %s\n", yytext); + return TOKEN_FLOAT_LITERAL; } '([[:print:]]|\\([abefnrtv\\'"]|0x[[:xdigit:]]{2}))' { @@ -69,44 +71,45 @@ while { printf("WHILE\n"); return T_WHILE; } printf("encoded: %s\n", es); es[strlen(es) - 1] = '\0'; printf("CHAR_LITERAL: %s\n", es + 1); - return T_CHAR_LITERAL; + return TOKEN_CHAR_LITERAL; } else { printf("ERROR: Invalid character literal: %s\n", yytext); - return T_ERROR; + return TOKEN_ERROR; } } + /* Operators */ -\+\+ { printf("INCREMENT\n"); return T_INCREMENT; } --- { printf("DECREMENT\n"); return T_DECREMENT; } -\^ { printf("EXPONENT\n"); return T_EXPONENT; } -\* { printf("MULTIPLY\n"); return T_MULTIPLY; } -\/ { printf("DIVIDE\n"); return T_DIVIDE; } -\% { printf("MODULO\n"); return T_MODULO; } -\+ { printf("ADD\n"); return T_ADD; } -- { printf("MINUS\n"); return T_MINUS; } -\< { printf("LESS\n"); return T_LESS; } -\<= { printf("LESS_OR_EQUAL\n"); return T_LESS_OR_EQUAL; } -> { printf("GREATER\n"); return T_GREATER; } ->= { printf("GREATER_OR_EQUAL\n"); return T_GREATER_OR_EQUAL; } -== { printf("EQUAL\n"); return T_EQUAL; } -!= { printf("NOT_EQUAL\n"); return T_NOT_EQUAL; } -&& { printf("LOGICAL_AND\n"); return T_LOGICAL_AND; } -\|\| { printf("LOGICAL_OR\n"); return T_LOGICAL_OR; } -! { printf("LOGICAL_NOT\n"); return T_LOGICAL_NOT; } -= { printf("ASSIGN\n"); return T_ASSIGN; } +\+\+ { printf("INCREMENT\n"); return TOKEN_INCREMENT; } +-- { printf("DECREMENT\n"); return TOKEN_DECREMENT; } +\^ { printf("EXPONENT\n"); return TOKEN_EXPONENT; } +\* { printf("MULTIPLY\n"); return TOKEN_MULTIPLY; } +\/ { printf("DIVIDE\n"); return TOKEN_DIVIDE; } +\% { printf("MODULO\n"); return TOKEN_MODULO; } +\+ { printf("ADD\n"); return TOKEN_ADD; } +- { printf("MINUS\n"); return TOKEN_MINUS; } +\< { printf("LESS\n"); return TOKEN_LESS; } +\<= { printf("LESS_OR_EQUAL\n"); return TOKEN_LESS_OR_EQUAL; } +> { printf("GREATER\n"); return TOKEN_GREATER; } +>= { printf("GREATER_OR_EQUAL\n"); return TOKEN_GREATER_OR_EQUAL; } +== { printf("EQUAL\n"); return TOKEN_EQUAL; } +!= { printf("NOT_EQUAL\n"); return TOKEN_NOT_EQUAL; } +&& { printf("LOGICAL_AND\n"); return TOKEN_LOGICAL_AND; } +\|\| { printf("LOGICAL_OR\n"); return TOKEN_LOGICAL_OR; } +! { printf("LOGICAL_NOT\n"); return TOKEN_LOGICAL_NOT; } += { printf("ASSIGN\n"); return TOKEN_ASSIGN; } /* Symbols */ -"(" { printf("LPAREN\n"); return T_LPAREN; } -")" { printf("RPAREN\n"); return T_RPAREN; } -"[" { printf("LBRACKET\n"); return T_LBRACKET; } -"]" { printf("RBRACKET\n"); return T_RBRACKET; } -"{" { printf("LBRACE\n"); return T_LBRACE; } -"}" { printf("RBRACE\n"); return T_RBRACE; } -; { printf("SEMICOLON\n"); return T_SEMICOLON; } -: { printf("COLON\n"); return T_COLON; } -, { printf("COMMA\n"); return T_COMMA; } +"(" { printf("LPAREN\n"); return TOKEN_LPAREN; } +")" { printf("RPAREN\n"); return TOKEN_RPAREN; } +"[" { printf("LBRACKET\n"); return TOKEN_LBRACKET; } +"]" { printf("RBRACKET\n"); return TOKEN_RBRACKET; } +"{" { printf("LBRACE\n"); return TOKEN_LBRACE; } +"}" { printf("RBRACE\n"); return TOKEN_RBRACE; } +; { printf("SEMICOLON\n"); return TOKEN_SEMICOLON; } +: { printf("COLON\n"); return TOKEN_COLON; } +, { printf("COMMA\n"); return TOKEN_COMMA; } \"([^"\\]*(\\.[^"\\]*)*)\" { @@ -115,10 +118,10 @@ while { printf("WHILE\n"); return T_WHILE; } char es[strlen(yytext) + 1]; string_encode((const char*) s, es); printf("STRING_LITERAL: %s\n", es); - return T_STRING_LITERAL; + return TOKEN_STRING_LITERAL; } else { printf("ERROR: Invalid string literal: %s\n", yytext); - return T_ERROR; + return TOKEN_ERROR; } } @@ -129,15 +132,20 @@ while { printf("WHILE\n"); return T_WHILE; } } <> { - return T_EOF; + // Returns 0 for subsequent calls + if (returned_eof) return 0; + returned_eof = 1; + return TOKEN_EOF; } + /* TODO: Comments */ + . { printf("ERROR: Invalid character %s\n", yytext); - return T_ERROR; + return TOKEN_ERROR; } - %% + int yywrap() { return 1; } diff --git a/parser.c b/parser.c new file mode 100644 index 0000000..715ea85 --- /dev/null +++ b/parser.c @@ -0,0 +1,19 @@ +#include + +extern int yyparse(); +extern FILE* yyin; +extern int yydebug; + +int parse(const char* filename) +{ + yydebug = 0; + yyin = fopen(filename, "r"); + if (!yyin) + { + fprintf(stderr, "Could not open file %s\n", filename); + return 1; + } + int result = yyparse(); + fclose(yyin); + return result; +} \ No newline at end of file diff --git a/parser.h b/parser.h new file mode 100644 index 0000000..e5b30b9 --- /dev/null +++ b/parser.h @@ -0,0 +1 @@ +int parse(char* filename); \ No newline at end of file diff --git a/runtest.sh b/runtest.sh index 3eb0fc4..0d4bcbf 100755 --- a/runtest.sh +++ b/runtest.sh @@ -16,6 +16,9 @@ case $module in "scanner") command="scan" ;; + "parser") + command="parse" + ;; *) echo "Unknown module: $module" exit 1 diff --git a/scanner.c b/scanner.c index c40b3cb..951a806 100644 --- a/scanner.c +++ b/scanner.c @@ -15,10 +15,10 @@ int scan(const char* filename) } int token = 1; // Initialize to a non-zero value - while (token != T_EOF) + while (token != TOKEN_EOF) { // Handle the tokens - if (token == T_ERROR) { + if (token == TOKEN_ERROR) { return 1; } token = yylex(); diff --git a/test/parser/bad0.bminor b/test/parser/bad0.bminor new file mode 100644 index 0000000..bc18605 --- /dev/null +++ b/test/parser/bad0.bminor @@ -0,0 +1 @@ +a : 10; \ No newline at end of file diff --git a/test/parser/bad1.bminor b/test/parser/bad1.bminor new file mode 100644 index 0000000..3ef1824 --- /dev/null +++ b/test/parser/bad1.bminor @@ -0,0 +1 @@ +a : integer 10 \ No newline at end of file diff --git a/test/parser/bad2.bminor b/test/parser/bad2.bminor new file mode 100644 index 0000000..632f0ac --- /dev/null +++ b/test/parser/bad2.bminor @@ -0,0 +1 @@ +a : array [] integer = { 1 ; 2; 3} ; \ No newline at end of file diff --git a/test/parser/bad3.bminor b/test/parser/bad3.bminor new file mode 100644 index 0000000..1eb97cc --- /dev/null +++ b/test/parser/bad3.bminor @@ -0,0 +1,2 @@ +a : integer = 10; +a += 10; \ No newline at end of file diff --git a/test/parser/good0.bminor b/test/parser/good0.bminor new file mode 100644 index 0000000..ae5bde9 --- /dev/null +++ b/test/parser/good0.bminor @@ -0,0 +1,2 @@ +a : float; +a : integer = 10; \ No newline at end of file diff --git a/test/parser/good1.bminor b/test/parser/good1.bminor new file mode 100644 index 0000000..950e5fa --- /dev/null +++ b/test/parser/good1.bminor @@ -0,0 +1,3 @@ +str : string = "Hello World!"; +some_char : char = '\0x41'; +some_char : char = 'a'; diff --git a/test/parser/good2.bminor b/test/parser/good2.bminor new file mode 100644 index 0000000..cc9aa23 --- /dev/null +++ b/test/parser/good2.bminor @@ -0,0 +1,3 @@ +main : function integer (args : string) = { + return 0; +} diff --git a/test/parser/good3.bminor b/test/parser/good3.bminor new file mode 100644 index 0000000..f84fca2 --- /dev/null +++ b/test/parser/good3.bminor @@ -0,0 +1,9 @@ +main : function integer (args : string) = { + result : integer = usage(); + return 0; +} + +usage : function void () = { + print "Usage", 10; + return; +} diff --git a/test/parser/good4.bminor b/test/parser/good4.bminor new file mode 100644 index 0000000..bc7fa3f --- /dev/null +++ b/test/parser/good4.bminor @@ -0,0 +1,11 @@ +a : integer; + +func : function void () = { + if ( a > 1) + { + a = a - 1; + } else { + a = a + 1; + } + +} \ No newline at end of file diff --git a/test/parser/good5.bminor b/test/parser/good5.bminor new file mode 100644 index 0000000..d18161f --- /dev/null +++ b/test/parser/good5.bminor @@ -0,0 +1,6 @@ +a : integer; + +func : function void () = { + if ( a > 1 ) a = a - 1; + else a = a + 1; +} \ No newline at end of file diff --git a/test/parser/good6.bminor b/test/parser/good6.bminor new file mode 100644 index 0000000..c64870d --- /dev/null +++ b/test/parser/good6.bminor @@ -0,0 +1,10 @@ +a : integer; + +func : function void () = { + for (i = 0; i++; i ^ 2) { + a = a + 1; + for (i = 0; i++; i ^ 2) { + a = a + 1; + } + } +} \ No newline at end of file diff --git a/token.h b/token.h deleted file mode 100644 index 1533239..0000000 --- a/token.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef TOKEN_H -#define TOKEN_H - -/* Keywords */ -#define T_ARRAY 256 -#define T_AUTO 257 -#define T_BOOLEAN 258 -#define T_CHAR 259 -#define T_ELSE 260 -#define T_FALSE 261 -#define T_FLOAT 262 -#define T_FOR 263 -#define T_FUNCTION 264 -#define T_IF 265 -#define T_INTEGER 266 -#define T_PRINT 267 -#define T_RETURN 268 -#define T_STRING 269 -#define T_TRUE 270 -#define T_VOID 271 -#define T_WHILE 272 - -/* Operators */ -#define T_INCREMENT 273 -#define T_DECREMENT 274 -#define T_EXPONENT 275 -#define T_MULTIPLY 276 -#define T_DIVIDE 277 -#define T_MODULO 278 -#define T_ADD 279 -#define T_MINUS 280 -#define T_LESS 281 -#define T_LESS_OR_EQUAL 282 -#define T_GREATER 283 -#define T_GREATER_OR_EQUAL 284 -#define T_EQUAL 285 -#define T_NOT_EQUAL 286 -#define T_LOGICAL_AND 287 -#define T_LOGICAL_OR 288 -#define T_LOGICAL_NOT 289 -#define T_ASSIGN 290 - -/* Symbols */ -#define T_LPAREN 291 -#define T_RPAREN 292 -#define T_LBRACKET 293 -#define T_RBRACKET 294 -#define T_LBRACE 295 -#define T_RBRACE 296 -#define T_SEMICOLON 297 -#define T_COLON 298 -#define T_COMMA 299 - -/* Identifiers and Literals */ -#define T_IDENTIFIER 300 -#define T_INTEGER_LITERAL 301 -#define T_FLOAT_LITERAL 302 -#define T_CHAR_LITERAL 303 -#define T_STRING_LITERAL 304 - -/* Error */ -#define T_EOF 305 -#define T_ERROR 306 - -#endif // TOKEN_H \ No newline at end of file