Skip to content
This repository was archived by the owner on Jun 28, 2024. It is now read-only.

Commit 35773a9

Browse files
committed
WIP
1 parent 00f692a commit 35773a9

20 files changed

+443
-182
lines changed

Makefile

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
bminor: bminor.c encoder.o scanner.o lex.yy.o
1+
bminor: bminor.c encoder.o scanner.o lex.yy.o parser.o grammar.tab.o
22
gcc $^ -o $@
33

44
encoder.o: encoder.c
@@ -10,7 +10,16 @@ lex.yy.c: lex.yy.l
1010
lex.yy.o: lex.yy.c
1111
gcc -c $^ -o $@
1212

13-
scanner.o: scanner.c
13+
scanner.o: scanner.c token.h
14+
gcc -c $< -o $@
15+
16+
parser.o: parser.c
17+
gcc -c $^ -o $@
18+
19+
grammar.tab.c token.h: grammar.y lex.yy.c
20+
bison -v --defines=token.h $<
21+
22+
grammar.tab.o: grammar.tab.c
1423
gcc -c $^ -o $@
1524

1625
# Tests
@@ -20,8 +29,12 @@ test-encoder:
2029
test-scanner:
2130
./runtest.sh scanner
2231

32+
test-parser:
33+
./runtest.sh parser
34+
2335
clean:
2436
rm -f lex.yy.c
37+
rm -f token.h grammar.tab.c grammar.output
2538
rm -f *.o
2639
rm -f ./test/*/*.bminor.out
2740
rm -f bminor

bminor.c

Lines changed: 41 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "encoder.h"
66
#include "scanner.h"
7+
#include "parser.h"
78

89
void usage(int exit_code)
910
{
@@ -13,61 +14,49 @@ void usage(int exit_code)
1314

1415
int main(int argc, char* argv[])
1516
{
17+
char* option, * filename;
1618

17-
if (argc == 1)
18-
usage(1);
19+
switch (argc)
20+
{
21+
case 1:
22+
usage(EXIT_FAILURE);
23+
break;
24+
case 2:
25+
if (strcmp(argv[1], "--help") == 0)
26+
usage(EXIT_SUCCESS);
27+
else usage(EXIT_FAILURE);
28+
break;
29+
case 3:
30+
option = argv[1];
31+
filename = argv[2];
32+
break;
33+
default:
34+
fprintf(stderr, "Too many arguments.\n");
35+
usage(EXIT_FAILURE);
36+
break;
37+
}
1938

20-
for (int i = 1; i < argc; i++)
39+
if (strcmp(option, "--encode") == 0)
40+
{
41+
if (decode(filename) == 0)
42+
return EXIT_SUCCESS;
43+
}
44+
else if (strcmp(option, "--scan") == 0)
45+
{
46+
if (scan(filename) == 0)
47+
return EXIT_SUCCESS;
48+
}
49+
else if (strcmp(option, "--parse") == 0)
50+
{
51+
if (parse(filename) == 0)
52+
return EXIT_SUCCESS;
53+
}
54+
else
2155
{
22-
if (argv[i][0] == '-')
23-
{
24-
if (strcmp(argv[i], "--help") == 0)
25-
usage(0);
26-
else if (strcmp(argv[i], "--encode") == 0)
27-
{
28-
const char* filename = argv[++i];
29-
if (filename)
30-
{
31-
if (decode(filename) == 0)
32-
return EXIT_SUCCESS;
33-
else
34-
{
35-
fprintf(stderr, "Failed to decode file %s\n", filename);
36-
return EXIT_FAILURE;
37-
}
38-
}
39-
else
40-
{
41-
fprintf(stderr, "Missing filename to be encoded\n");
42-
return EXIT_FAILURE;
43-
}
44-
}
45-
else if (strcmp(argv[i], "--scan") == 0)
46-
{
47-
const char* filename = argv[++i];
48-
if (filename)
49-
{
50-
if (scan(filename) == 0)
51-
return EXIT_SUCCESS;
52-
else
53-
{
54-
fprintf(stderr, "Failed to scan file %s\n", filename);
55-
return EXIT_FAILURE;
56-
}
57-
}
58-
else
59-
{
60-
fprintf(stderr, "Missing filename to be scanned\n");
61-
return EXIT_FAILURE;
62-
}
63-
}
64-
else
65-
{
66-
fprintf(stderr, "Unknown option '%s'\n", argv[i]);
67-
usage(1);
68-
}
69-
}
56+
fprintf(stderr, "Unknown option '%s'\n", option);
57+
usage(EXIT_FAILURE);
7058
}
7159

72-
return EXIT_SUCCESS;
60+
fprintf(stderr, "Failed to %s file %s\n", option + 2, filename);
61+
return EXIT_FAILURE;
7362
}

grammar.y

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
%{
2+
#include <stdio.h>
3+
#define YYDEBUG 1
4+
5+
extern int yylex();
6+
extern int yylineno;
7+
extern char *yytext;
8+
9+
void yyerror(const char *s) {
10+
fprintf(stderr, "Error: %s at line %d near '%s'\n", s, yylineno, yytext);
11+
}
12+
%}
13+
14+
/* Keywords */
15+
%token TOKEN_ARRAY
16+
%token TOKEN_AUTO
17+
%token TOKEN_BOOLEAN
18+
%token TOKEN_CHAR
19+
%token TOKEN_ELSE
20+
%token TOKEN_FALSE
21+
%token TOKEN_FLOAT
22+
%token TOKEN_FOR
23+
%token TOKEN_FUNCTION
24+
%token TOKEN_IF
25+
%token TOKEN_INTEGER
26+
%token TOKEN_PRINT
27+
%token TOKEN_RETURN
28+
%token TOKEN_STRING
29+
%token TOKEN_TRUE
30+
%token TOKEN_VOID
31+
%token TOKEN_WHILE
32+
33+
/* Operators */
34+
%token TOKEN_INCREMENT
35+
%token TOKEN_DECREMENT
36+
%token TOKEN_EXPONENT
37+
%token TOKEN_MULTIPLY
38+
%token TOKEN_DIVIDE
39+
%token TOKEN_MODULO
40+
%token TOKEN_ADD
41+
%token TOKEN_MINUS
42+
%token TOKEN_LESS
43+
%token TOKEN_LESS_OR_EQUAL
44+
%token TOKEN_GREATER
45+
%token TOKEN_GREATER_OR_EQUAL
46+
%token TOKEN_EQUAL
47+
%token TOKEN_NOT_EQUAL
48+
%token TOKEN_LOGICAL_AND
49+
%token TOKEN_LOGICAL_OR
50+
%token TOKEN_LOGICAL_NOT
51+
%token TOKEN_ASSIGN
52+
53+
/* Symbols */
54+
%token TOKEN_LPAREN
55+
%token TOKEN_RPAREN
56+
%token TOKEN_LBRACKET
57+
%token TOKEN_RBRACKET
58+
%token TOKEN_LBRACE
59+
%token TOKEN_RBRACE
60+
%token TOKEN_SEMICOLON
61+
%token TOKEN_COLON
62+
%token TOKEN_COMMA
63+
64+
/* Identifiers and Literals */
65+
%token TOKEN_ID
66+
%token TOKEN_INT_LITERAL
67+
%token TOKEN_FLOAT_LITERAL
68+
%token TOKEN_CHAR_LITERAL
69+
%token TOKEN_STRING_LITERAL
70+
71+
/* Error */
72+
%token TOKEN_EOF
73+
%token TOKEN_ERROR
74+
75+
%%
76+
prog : decl_list TOKEN_EOF
77+
;
78+
79+
/* Declarations */
80+
81+
decl_list : /* epsilon */
82+
| decl_list decl
83+
;
84+
85+
decl : param TOKEN_SEMICOLON
86+
| param TOKEN_ASSIGN init
87+
;
88+
89+
init : expr TOKEN_SEMICOLON
90+
| TOKEN_LBRACE opt_stmt_list TOKEN_RBRACE /* function body */
91+
| TOKEN_LBRACE expr_list TOKEN_RBRACE /* array */
92+
;
93+
94+
/* Statements */
95+
96+
opt_stmt_list : /* epsilon */
97+
| stmt_list
98+
;
99+
100+
stmt_list : stmt
101+
| stmt_list stmt
102+
;
103+
104+
stmt : TOKEN_LBRACE stmt_list TOKEN_RBRACE
105+
| for_loop
106+
| if_cond
107+
| print_stmt
108+
| return_stmt
109+
| decl
110+
| expr TOKEN_SEMICOLON
111+
;
112+
113+
for_loop : TOKEN_FOR TOKEN_LPAREN
114+
opt_expr TOKEN_SEMICOLON opt_expr TOKEN_SEMICOLON opt_expr
115+
TOKEN_RPAREN stmt
116+
;
117+
118+
if_cond : TOKEN_IF TOKEN_LPAREN opt_expr TOKEN_RPAREN else_stmt
119+
;
120+
121+
else_stmt : TOKEN_ELSE stmt
122+
| /* epsilon */
123+
;
124+
125+
print_stmt : TOKEN_PRINT opt_expr_list TOKEN_SEMICOLON
126+
;
127+
128+
return_stmt : TOKEN_RETURN opt_expr TOKEN_SEMICOLON
129+
;
130+
131+
/* Expressions */
132+
133+
opt_expr_list : /* epsilon */
134+
| expr_list
135+
;
136+
137+
expr_list : expr
138+
| expr_list TOKEN_COMMA expr
139+
;
140+
141+
opt_expr : /* epsilon */
142+
| expr
143+
;
144+
145+
expr : expr1
146+
;
147+
148+
expr1 : lval TOKEN_ASSIGN expr1
149+
| expr2
150+
;
151+
152+
lval : TOKEN_ID
153+
| TOKEN_ID index
154+
;
155+
156+
expr2 : expr2 TOKEN_LOGICAL_OR expr3
157+
| expr3
158+
;
159+
160+
expr3 : expr3 TOKEN_LOGICAL_AND expr4
161+
| expr4
162+
;
163+
164+
expr4 : expr4 TOKEN_EQUAL expr5
165+
| expr4 TOKEN_NOT_EQUAL expr5
166+
| expr4 TOKEN_LESS expr5
167+
| expr4 TOKEN_LESS_OR_EQUAL expr5
168+
| expr4 TOKEN_GREATER expr5
169+
| expr4 TOKEN_GREATER_OR_EQUAL expr5
170+
| expr5
171+
;
172+
173+
expr5 : expr5 TOKEN_ADD expr6
174+
| expr5 TOKEN_MINUS expr6
175+
| expr6
176+
;
177+
178+
expr6 : expr6 TOKEN_MULTIPLY expr7
179+
| expr6 TOKEN_DIVIDE expr7
180+
| expr6 TOKEN_MODULO expr7
181+
| expr7
182+
;
183+
184+
expr7 : expr7 TOKEN_EXPONENT expr8
185+
| expr8
186+
;
187+
188+
expr8 : TOKEN_MINUS expr8
189+
| TOKEN_LOGICAL_NOT expr8
190+
| expr9
191+
;
192+
193+
expr9 : expr9 TOKEN_INCREMENT
194+
| expr9 TOKEN_DECREMENT
195+
| group
196+
;
197+
198+
group : TOKEN_LPAREN expr TOKEN_RPAREN
199+
| TOKEN_ID TOKEN_LPAREN opt_expr_list TOKEN_RPAREN
200+
| TOKEN_ID index
201+
| factor
202+
;
203+
204+
index : TOKEN_LBRACKET expr TOKEN_RBRACKET
205+
;
206+
207+
factor : TOKEN_ID
208+
| TOKEN_INT_LITERAL
209+
| TOKEN_FLOAT_LITERAL
210+
| TOKEN_CHAR_LITERAL
211+
| TOKEN_STRING_LITERAL
212+
| TOKEN_TRUE
213+
| TOKEN_FALSE
214+
;
215+
216+
/* Types */
217+
218+
type : TOKEN_INTEGER
219+
| TOKEN_FLOAT
220+
| TOKEN_BOOLEAN
221+
| TOKEN_CHAR
222+
| TOKEN_STRING
223+
| TOKEN_VOID
224+
| TOKEN_ARRAY index type
225+
| type_func
226+
;
227+
228+
type_func : TOKEN_FUNCTION type TOKEN_LPAREN opt_param_list TOKEN_RPAREN
229+
;
230+
231+
opt_param_list : /* epsilon */
232+
| param_list
233+
;
234+
235+
param_list : param
236+
| param_list TOKEN_COMMA param
237+
;
238+
239+
param : TOKEN_ID TOKEN_COLON type
240+
;
241+
242+
%%
243+
244+
// int yywrap() { return 0; }

0 commit comments

Comments
 (0)