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

Commit 160bd09

Browse files
committed
Introduce printer
* Create test cases for printer * Add printer test in runtest.sh * Add --print option * Add rules for printer and other improvements * Create printer.c * Define semantic values in lex.yy.l * Modify parse() to support parsing consecutive files * Modify parse() to return AST root * Add actions after reduction in grammar.y * Add param_list_create() and param_list_print() * Add expr_create() and expr_print() * Add type_create() and type_print() * Add stmt_create() and stmt_print() * Add decl_create() and decl_print() * Pass file pointers to decode(), scan(), and parse() * Modify parse() to take file pointer * Modify scan() to take file pointer * Modify decode() to take file pointer * Move definition of MAX_STRING_LEN * Add grammar.output to .gitignore
1 parent aaab449 commit 160bd09

35 files changed

+1193
-178
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ bminor
88
lex.yy.c
99
token.h
1010
grammar.tab.c
11+
grammar.output
1112

1213
test/**/*.out

Makefile

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
bminor: bminor.c encoder.o scanner.o lex.yy.o parser.o grammar.tab.o
1+
bminor: bminor.c encoder.o scanner.o lex.yy.o parser.o grammar.tab.o printer.o decl.o stmt.o expr.o type.o param_list.o
22
gcc $^ -o $@
33

4-
encoder.o: encoder.c
5-
gcc -c $^ -o $@
4+
encoder.o: encoder.c encoder.h
5+
gcc -c $< -o $@
66

7+
# Scanner
78
lex.yy.c: lex.yy.l
89
flex $^
910

@@ -13,16 +14,36 @@ lex.yy.o: lex.yy.c
1314
scanner.o: scanner.c token.h
1415
gcc -c $< -o $@
1516

17+
# Parser
1618
parser.o: parser.c
1719
gcc -c $^ -o $@
1820

1921
grammar.tab.c token.h: grammar.y lex.yy.c
20-
bison --defines=token.h $<
21-
#bison -v --defines=token.h $<
22+
#bison --defines=token.h $<
23+
bison -v --defines=token.h $<
2224

2325
grammar.tab.o: grammar.tab.c
2426
gcc -c $^ -o $@
2527

28+
# Printer
29+
printer.o: printer.c
30+
gcc -c $^ -o $@
31+
32+
decl.o: decl.c
33+
gcc -c $^ -o $@
34+
35+
stmt.o: stmt.c
36+
gcc -c $^ -o $@
37+
38+
expr.o: expr.c
39+
gcc -c $^ -o $@
40+
41+
type.o: type.c
42+
gcc -c $^ -o $@
43+
44+
param_list.o: param_list.c
45+
gcc -c $^ -o $@
46+
2647
# Tests
2748
test-encoder:
2849
./runtest.sh encoder
@@ -33,9 +54,12 @@ test-scanner:
3354
test-parser:
3455
./runtest.sh parser
3556

57+
test-printer:
58+
./runtest.sh printer
59+
3660
clean:
3761
rm -f lex.yy.c
3862
rm -f token.h grammar.tab.c grammar.output
3963
rm -f *.o
4064
rm -f ./test/*/*.bminor.out
41-
rm -f bminor
65+
rm -f bminor

bminor.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "encoder.h"
66
#include "scanner.h"
77
#include "parser.h"
8+
#include "printer.h"
89

910
void usage(int exit_code)
1011
{
@@ -14,8 +15,8 @@ void usage(int exit_code)
1415

1516
int main(int argc, char* argv[])
1617
{
18+
// Parse command line arguments
1719
char* option, * filename;
18-
1920
switch (argc)
2021
{
2122
case 1:
@@ -36,27 +37,41 @@ int main(int argc, char* argv[])
3637
break;
3738
}
3839

40+
// Open input file
41+
FILE* fp = fopen(filename, "r");
42+
if (fp == NULL)
43+
{
44+
fprintf(stderr, "Failed to open file %s\n", filename);
45+
return EXIT_FAILURE;
46+
}
47+
48+
// Perform the requested operation
3949
if (strcmp(option, "--encode") == 0)
4050
{
41-
if (decode(filename) == 0)
51+
if (decode(fp) == 0)
4252
return EXIT_SUCCESS;
4353
}
4454
else if (strcmp(option, "--scan") == 0)
4555
{
46-
if (scan(filename) == 0)
56+
if (scan(fp) == 0)
4757
return EXIT_SUCCESS;
4858
}
4959
else if (strcmp(option, "--parse") == 0)
5060
{
51-
if (parse(filename) == 0)
61+
if (parse(fp) != NULL)
5262
return EXIT_SUCCESS;
5363
}
64+
else if (strcmp(option, "--print") == 0)
65+
{
66+
return print_and_compare(filename, fp);
67+
}
5468
else
5569
{
5670
fprintf(stderr, "Unknown option '%s'\n", option);
5771
usage(EXIT_FAILURE);
5872
}
5973

74+
//Error message
6075
fprintf(stderr, "Failed to %s file %s\n", option + 2, filename);
6176
return EXIT_FAILURE;
6277
}

decl.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <stdlib.h>
2+
#include <stdio.h>
3+
#include "decl.h"
4+
#include "type.h"
5+
6+
struct decl* decl_create(char* name, struct type* type, struct expr* value, struct stmt* code, struct decl* next)
7+
{
8+
struct decl* d = malloc(sizeof(*d));
9+
d->name = name;
10+
d->type = type;
11+
d->value = value;
12+
d->code = code;
13+
d->next = next;
14+
return d;
15+
}
16+
17+
void decl_print(struct decl* d, int indent)
18+
{
19+
if (!d) return;
20+
int i;
21+
22+
for (i = 0; i < indent; i++)
23+
printf("\t");
24+
printf("%s: ", d->name);
25+
type_print(d->type);
26+
27+
if (d->value)
28+
{
29+
printf(" = ");
30+
if (d->value->kind == EXPR_LIST)
31+
{
32+
printf("{");
33+
expr_print(d->value);
34+
printf("}");
35+
}
36+
else
37+
{
38+
expr_print(d->value);
39+
}
40+
}
41+
42+
if (d->code)
43+
{
44+
printf(" = {\n");
45+
stmt_print(d->code, indent + 1);
46+
for (i = 0; i < indent; i++)
47+
printf("\t");
48+
printf("}");
49+
}
50+
else
51+
{
52+
// Functions don't end with semicolon
53+
printf(";");
54+
}
55+
56+
printf("\n");
57+
decl_print(d->next, indent);
58+
}

decl.h

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
1-
21
#ifndef DECL_H
32
#define DECL_H
43

5-
#include "type.h"
64
#include "stmt.h"
75
#include "expr.h"
8-
#include <stdio.h>
6+
#include "symbol.h"
97

10-
struct decl {
11-
char *name;
12-
struct type *type;
13-
struct expr *value;
14-
struct stmt *code;
15-
struct symbol *symbol;
16-
struct decl *next;
8+
struct decl
9+
{
10+
char* name;
11+
struct type* type;
12+
struct expr* value;
13+
struct stmt* code;
14+
struct symbol* symbol;
15+
struct decl* next;
1716
};
1817

19-
struct decl * decl_create( char *name, struct type *type, struct expr *value, struct stmt *code, struct decl *next );
20-
void decl_print( struct decl *d, int indent );
18+
struct decl* decl_create(char* name, struct type* type, struct expr* value, struct stmt* code, struct decl* next);
19+
void decl_print(struct decl* d, int indent);
2120

2221
#endif
23-
24-

encoder.c

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#include <stdlib.h>
22
#include <stdio.h>
33
#include <string.h>
4-
5-
#define MAX_STRING_LEN 255
4+
#include "encoder.h"
65

76
int is_hex(char c)
87
{
@@ -199,40 +198,32 @@ int string_encode(const char* s, char* es)
199198
return 0;
200199
}
201200

202-
int decode(const char* filename)
201+
int decode(FILE* fp)
203202
{
204-
FILE* file = fopen(filename, "r");
205-
if (file == NULL)
206-
{
207-
printf("Could not open file %s\n", filename);
208-
return 1;
209-
}
210-
211203
// Find the size of the file
212-
fseek(file, 0, SEEK_END);
213-
long file_size = ftell(file);
204+
fseek(fp, 0, SEEK_END);
205+
long file_size = ftell(fp);
214206
if (file_size > (MAX_STRING_LEN * 5 + 2) * sizeof(char))
215207
{
216208
fprintf(stderr, "Invalid string: too long\n");
217-
fclose(file);
209+
fclose(fp);
218210
return 1;
219211
}
220-
rewind(file);
212+
rewind(fp);
221213

222214
// Allocate memory for the file content
223215
// Reserve space for \0
224216
char* file_content = (char*)malloc(file_size + sizeof(char));
225217
if (file_content == NULL)
226218
{
227219
perror("Could not allocate memory");
228-
fclose(file);
220+
fclose(fp);
229221
return 1;
230222
}
231223

232224
// Read the file content into the allocated memory
233-
size_t chars_read = fread(file_content, sizeof(char), file_size, file);
225+
size_t chars_read = fread(file_content, sizeof(char), file_size, fp);
234226
file_content[chars_read] = '\0';
235-
fclose(file);
236227

237228
char s[MAX_STRING_LEN + 1] = { 0 };
238229

encoder.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
#ifndef ENCODER_H
2+
#define ENCODER_H
3+
14
#define MAX_STRING_LEN 255
25

36
int string_decode(const char* es, char* s);
47

58
int string_encode(const char* s, char* es);
69

7-
int decode(const char* filename);
10+
int decode(FILE *fp);
11+
12+
#endif

0 commit comments

Comments
 (0)