aboutsummaryrefslogtreecommitdiffstats
path: root/c_compiler/src/c_parser.y
blob: 7a3899b47e3687a99a72ea3dffd9dd4b88036f86 (plain)
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
%code requires{

#include "ast.hpp"
    
extern TranslationUnit* g_root; // A way of getting the AST out

//! This is to fix problems when generating C++
// We are declaring the functions provided by Flex, so
// that Bison generated code can call them.
int yylex(void);
void yyerror(const char *);

}

// Represents the value associated with any kind of
// AST node.
%union{
    Node* node;
    TranslationUnit* trans_unit;
    Function* function;
    Type* type;
    Initializer* initializer;
    Declaration* declaration;
    double number;
    std::string* string;
}
                        
%token			T_TYPE_SPEC T_TYPE_QUAL T_STRG_SPEC T_IDENTIFIER T_SC T_CMA T_LRB T_LCB T_RCB
			T_LSB T_RSB T_QU T_COL T_LOG_OR T_LOG_AND T_OR T_XOR T_AND T_EQUALITY_OP
			T_REL_OP T_SHIFT_OP T_MULT T_DIV T_REM T_TILDE T_NOT T_DOT T_ARROW T_INCDEC
			T_ADDSUB_OP T_ASSIGN_OPER T_EQ T_SIZEOF T_INT_CONST T_IF T_WHILE T_DO T_FOR
			T_RETURN
			
%nonassoc		T_RRB
%nonassoc		T_ELSE
			
%type	<node>		ExternalDeclaration
			
%type	<trans_unit>	TranslationUnit
			
%type	<function>	FunctionDefinition

%type	<declaration>	Parameter Declaration InitDeclaratorList InitDeclarator ParameterList

%type	<type>		DeclarationSpec

%type	<string>	Declarator DirectDeclarator
			
%type	<number>        T_INT_CONST

%type	<initializer>	Initializer
			
%type	<string>	T_IDENTIFIER T_ASSIGN_OPER T_EQ T_AND T_ADDSUB_OP T_TILDE T_NOT
			T_MULT T_DIV T_REM
                        
%start ROOT
                        
%%

ROOT:
	        TranslationUnit { g_root = $1; }
		;

// TRANSLATION UNIT

TranslationUnit:
		ExternalDeclaration { $$ = new TranslationUnit($1); }
	|       TranslationUnit ExternalDeclaration { $$->push($2); }
		;

ExternalDeclaration:
		Declaration { $$ = $1; }
        |       FunctionDefinition { $$ = $1; }
		;

// FUNCTION DEFINITION

FunctionDefinition:
		DeclarationSpec T_IDENTIFIER T_LRB ParameterList T_RRB T_SC { $$ = new Function(*$2, $4); }
		;

ParameterList:
		%empty { $$ = new Declaration(); }
	| 	Parameter { $$ = $1; }
	|       ParameterList T_CMA Parameter { $3->addDeclaration($$); $$ = $3; }
		;

Parameter:
		DeclarationSpec T_IDENTIFIER { $$ = new Declaration(*$2); }
		;

// Declaration

Declaration:
		DeclarationSpec InitDeclaratorList T_SC { $$ = $2; }
		;

DeclarationSpec:
		DeclarationSpec_T { ; }
	|	DeclarationSpec_T DeclarationSpec { ; }
		;

DeclarationSpec_T:
		T_TYPE_SPEC { ; }
	|	T_TYPE_QUAL { ; }
	|	T_STRG_SPEC { ; }
		;

InitDeclaratorList:
		InitDeclarator { $$ = $1; }
	|       InitDeclaratorList T_CMA InitDeclarator { $3->addDeclaration($$); $$ = $3; }
		;

InitDeclarator:
		Declarator { $$ = new Declaration(*$1); }
	|	Declarator T_EQ Initializer { $$ = new Declaration(*$1); }
		;

Initializer:
		T_INT_CONST { $$ = new Initializer(); }
	;

Declarator:
		DirectDeclarator { $$ = $1; }
	|	T_MULT DirectDeclarator { $$ = $2; }
		;

DirectDeclarator:
		T_IDENTIFIER { $$ = $1; }
		;

%%

TranslationUnit* g_root; // Definition of variable (to match declaration earlier)

TranslationUnit* parseAST() {
    g_root = 0;
    yyparse();
    return g_root;
}