-
Notifications
You must be signed in to change notification settings - Fork 1
/
BabyC.y
140 lines (114 loc) · 3.14 KB
/
BabyC.y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
* Bison Parser for a Baby C language
* Author: Kyle Szombathy
*/
%{
#include <stdio.h>
#include "BabyC_code.h"
// The parser needs to call the scanner to get the next token
extern int yylex();
// The error function
extern int yyerror(const char *);
// The ASTNode root
extern ASTNode* gASTRoot;
%}
//Put any initialization code here
%initial-action
{
}
%token LE "<="
%token LT "<"
%token GE ">="
%token GT ">"
%token EQ "=="
%token NE "!="
%token OR "||"
%token AND "&&"
%token MAIN "main"
%token INT "int"
%token IF "if"
%token ELSE "else"
%token WHILE "while"
//Define the types for the grammar attributes ($$, $1, $2, ...)
%union
{
ASTNode* node; // Most $$ values will be ASTNodes
int num; // Integer numbers
char* string; // Strings for identifiers
}
//Specify the type for each token. Only needed for IDENT and NUM, because they are the only ones that have actual regexp rules
%token <string> IDENT
%token <num> NUM
//Specify the type for each non-terminal in the grammar. Here are some samples:
%type <node> Goal
%type <node> DeclarationList
%type <node> Declaration
%type <node> StatementList
%type <node> Statement
%type <node> Assignment
%type <node> Expr
%type <node> Term
%type <node> Factor
%type <node> If
%type <node> While
%type <node> Condition
%type <node> Compare
// Add the rest of the types for the grammar's symbols
%%
// Write the grammar for BabyC, and write an embedded action for each production. Here are some samples for you:
Goal: "main" '(' ')' '{' DeclarationList StatementList '}' {gASTRoot=$6;} // Store the AST root node in gASTRoot
;
DeclarationList
:
| Declaration DeclarationList // Note that a DeclarationList may be empty
;
Declaration: "int" IDENT ';' {AddDeclaration($2);}
;
StatementList
: {$$ = NULL; }
| Statement StatementList {$$ = CreateStatementListNode($1, $2);}
;
Statement
: Assignment {$$ = $1;}
| If {$$ = $1;}
| While {$$ = $1;}
;
Assignment
: IDENT '=' Expr ';' {$$ = CreateAssignNode($1, $3);}
;
Expr
: Term {$$ = $1; }
| Expr '+' Term {$$ = CreateAddNode($1, $3); }
| Expr '-' Term {$$ = CreateSubNode($1, $3); }
;
Term
: Factor {$$ = $1;}
| Term '*' Factor {$$ = CreateMultNode($1, $3); }
| Term '/' Factor {$$ = CreateDivNode($1, $3); }
;
Factor
: IDENT {$$ = CreateIdentNode($1);}
| NUM {$$ = CreateNumNode($1); }
| '('Expr')' {$$ = $2; }
;
If
: IF '(' Condition ')' '{' StatementList '}' {$$ = CreateIfNode($3, $6, NULL);}
| IF '(' Condition ')' '{' StatementList '}' ELSE '{' StatementList '}' {$$ = CreateIfNode($3, $6, $10);}
;
While
: WHILE '(' Condition ')' '{' StatementList '}' {$$ = CreateWhileNode($3, $6);}
;
Condition
: Compare AND Compare {$$ = CreateAndNode($1, $3);}
| Compare OR Compare {$$ = CreateOrNode($1, $3);}
| Compare {$$ = $1;}
;
Compare
: Expr LE Expr {$$ = CreateLENode($1,$3);}
| Expr LT Expr {$$ = CreateLTNode($1,$3);}
| Expr GE Expr {$$ = CreateGENode($1,$3);}
| Expr GT Expr {$$ = CreateGTNode($1,$3);}
| Expr EQ Expr {$$ = CreateEQNode($1,$3);}
| Expr NE Expr {$$ = CreateNENode($1,$3);}
;
%%