-
Notifications
You must be signed in to change notification settings - Fork 165
/
c.tex
154 lines (152 loc) · 3.41 KB
/
c.tex
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
141
142
143
144
145
146
147
148
149
150
151
152
153
\begin{figure}
\begin{boxedminipage}[t]{\textwidth}
\begin{minipage}[l]{0.5\textwidth}
\normalsize
\textbf{A. Abstract Syntax}
\scriptsize
\begin{verbatim}
struct PROG_ {
enum {is_PROG} kind;
union {
struct { ListEXP listexp_; } prog_;
} u;
};
typedef struct PROG_ *PROG;
struct EXP_ {
enum { is_EOr, is_EAnd, is_ETrue,
is_EFalse, is_EVar } kind;
union {
struct { EXP exp_1, exp_2; } eor_;
struct { EXP exp_1, exp_2; } eand_;
struct { Ident ident_; } evar_;
} u;
};
typedef struct EXP_ *EXP;
struct ListEXP_ {
EXP exp_;
ListEXP listexp_;
};
typedef struct ListEXP_ *ListEXP;
\end{verbatim}
\normalsize
\textbf{B. Constructor Functions}
\scriptsize
\begin{verbatim}
EXP make_EOr(EXP p1, EXP p2) {
EXP tmp = (EXP) malloc(sizeof(*tmp));
if (!tmp) {
fprintf(stderr,
"Error: out of memory!\n");
exit(1);
}
tmp->kind = is_EOr;
tmp->u.eor_.exp_1 = p1;
tmp->u.eor_.exp_2 = p2;
return tmp;
}
EXP make_EAnd(EXP p1, EXP p2)
{
...
\end{verbatim}
\normalsize
\textbf{C. Bison Parser}
\scriptsize
\begin{verbatim}
PROGRAM YY_RESULT_PROGRAM_ = 0;
PROGRAM pPROGRAM(FILE *inp) {
initialize_lexer(inp);
if (yyparse()) /* Failure */
return 0;
else /* Success */
return YY_RESULT_PROGRAM_;
}
...
%token _ERROR_ /* Terminal */
%token _SYMB_0 /* || */
%token _SYMB_1 /* && */
%token _SYMB_2 /* ; */
%token _SYMB_3 /* ( */
%token _SYMB_4 /* ) */
%token _SYMB_5 /* false */
%token _SYMB_6 /* true */
...
\end{verbatim}
\normalsize
\end{minipage}
\hfill
\begin{minipage}[r]{0.5\textwidth}
\normalsize
\textbf{Bison Parser Continued}
\scriptsize
\begin{verbatim}
%%
PROGRAM : ListEXP {
$$ = make_PROGRAM(reverseListEXP($1));
YY_RESULT_PROGRAM_= $$; }
;
EXP : EXP _SYMB_0 EXP1 {
$$ = make_EOr($1, $3);
YY_RESULT_EXP_= $$; }
| EXP1 { $$ = $1; YY_RESULT_EXP_= $$; }
;
EXP1 : EXP1 _SYMB_1 EXP2 {
$$ = make_EAnd($1, $3);
YY_RESULT_EXP_= $$; }
| EXP2 { $$ = $1; YY_RESULT_EXP_= $$; }
;
EXP2 : _SYMB_6 { $$ = make_ETrue();
YY_RESULT_EXP_= $$; }
| _SYMB_5 { $$ = make_EFalse();
YY_RESULT_EXP_= $$; }
| _IDENT_ { $$ = make_EVar($1);
YY_RESULT_EXP_= $$; }
| _SYMB_3 EXP _SYMB_4 { $$ = $2;
YY_RESULT_EXP_= $$; }
;
ListEXP : /* empty */ { $$ = 0;
YY_RESULT_ListEXP_= $$; }
| ListEXP EXP _SYMB_2 {
$$ = make_ListEXP($2, $1);
YY_RESULT_ListEXP_= $$; }
;
\end{verbatim}
\normalsize
\textbf{D. Pretty Printer}
\scriptsize
\begin{verbatim}
...
void ppEXP(EXP _p_, int _i_) {
switch(_p_->kind) {
case is_EOr:
if (_i_ > 0) renderC(_L_PAREN);
ppEXP(_p_->u.eor_.exp_1, 0);
renderS("||");
ppEXP(_p_->u.eor_.exp_2, 1);
if (_i_ > 0) renderC(_R_PAREN);
break;
case is_EAnd:
if (_i_ > 1) renderC(_L_PAREN);
ppEXP(_p_->u.eand_.exp_1, 1);
renderS("&&");
...
void ppListEXP(ListEXP listexp, int i) {
while(listexp!= 0) {
if (listexp->listexp_ == 0) {
ppEXP(listexp->exp_, 0);
renderC(';');
listexp = 0;
} else {
ppEXP(listexp->exp_, 0);
renderC(';');
listexp = listexp->listexp_;
}
}
}
\end{verbatim}
\normalsize
\hfill
\end{minipage}
\end{boxedminipage}
\caption{C source code fragments generated from Figure \ref{fig:source}}
\label{fig:c}
\end{figure}