1 %{
2 /* 								-*- c -*-
3  * Grammar for states.
4  * Copyright (c) 1997-1998 Markku Rossi.
5  *
6  * Author: Markku Rossi <mtr@iki.fi>
7  */
8 
9 /*
10  * This file is part of GNU Enscript.
11  *
12  * Enscript is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * Enscript is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with Enscript.  If not, see <http://www.gnu.org/licenses/>.
24  */
25 
26 /*
27  * $Id: gram.y,v 1.1.1.1 2003/03/05 07:25:52 mtr Exp $
28  */
29 
30 #include "defs.h"
31 %}
32 
33 %union
34 {
35   List *lst;
36   Node *node;
37   Cons *cons;
38   Stmt *stmt;
39   Expr *expr;
40 }
41 
42 %token <node> tSYMBOL tREGEXP tSTRING tINTEGER tREAL
43 %token tSUB tSTATE tSTART tSTARTRULES tNAMERULES tBEGIN tEND tRETURN tIF tELSE
44 %token tLOCAL tWHILE tFOR tEXTENDS
45 
46 %right '=' tADDASSIGN tSUBASSIGN tMULASSIGN tDIVASSIGN
47 %right '?' ':'
48 %left tOR
49 %left tAND
50 %left tEQ tNE
51 %left '<' '>' tGE tLE
52 %left '+' '-'
53 %left '*' tDIV
54 %right '!' tPLUSPLUS tMINUSMINUS
55 %left '[' ']'
56 
57 %type <lst> regexp_sym_list symbol_list rest_symbol_list staterules
58 %type <lst> stmt_list expr_list rest_expr_list locals locals_rest
59 %type <stmt> stmt
60 %type <expr> expr cond_expr
61 %type <cons> staterule local_def
62 
63 %%
64 
65 file	: /* empty */
66 	| file toplevel
67 	;
68 
69 toplevel : tSTART '{' stmt_list '}'	{ start_stmts = $3; }
70 	| tSTARTRULES '{' regexp_sym_list '}'
71 					{ startrules = $3; }
72 	| tNAMERULES '{' regexp_sym_list '}'
73 					{ namerules = $3; }
74 	| tSTATE tSYMBOL '{' staterules '}'
75 					{ define_state ($2, NULL, $4); }
76 	| tSTATE tSYMBOL tEXTENDS tSYMBOL '{' staterules '}'
77 					{ define_state ($2, $4, $6); }
78 	| stmt				{ list_append (global_stmts, $1); }
79 	;
80 
81 regexp_sym_list : /* empty */ 		{ $$ = list (); }
82 	| regexp_sym_list tREGEXP tSYMBOL ';'
83 					{ list_append ($1, cons ($2, $3)); }
84 	;
85 
86 staterules : /* empty */ 		{ $$ = list (); }
87 	| staterules staterule		{ list_append ($1, $2); }
88 
89 staterule : tBEGIN '{' stmt_list '}' 	{ $$ = cons (RULE_BEGIN, $3); }
90 	| tEND '{' stmt_list '}' 	{ $$ = cons (RULE_END, $3); }
91 	| tREGEXP '{' stmt_list '}'	{ $$ = cons ($1, $3); }
92 	| tSYMBOL '{' stmt_list '}'	{ $$ = cons ($1, $3); }
93 	;
94 
95 symbol_list : /* empty */		{ $$ = list (); }
96 	| rest_symbol_list	 	{ $$ = $1; }
97 	;
98 
99 rest_symbol_list : tSYMBOL		{ $$ = list (); list_append ($$, $1); }
100 	| rest_symbol_list ',' tSYMBOL 	{ list_append ($1, $3); }
101 	;
102 
103 locals	: /* empty */			{ $$ = list (); }
104 	| tLOCAL locals_rest ';'	{ $$ = $2; }
105 	;
106 
107 locals_rest : local_def			{ $$ = list (); list_append ($$, $1); }
108 	| locals_rest ',' local_def	{ list_append ($1, $3); }
109 	;
110 
111 local_def : tSYMBOL			{ $$ = cons ($1, NULL); }
112 	| tSYMBOL '=' expr		{ $$ = cons ($1, $3); }
113 	;
114 
115 stmt_list : /* empty */			{ $$ = list (); }
116 	| stmt_list stmt 		{ list_append ($1, $2); }
117 	;
118 
119 stmt	: tRETURN ';'			{ $$ = mk_stmt (sRETURN, NULL, NULL,
120 							NULL, NULL); }
121 	| tRETURN expr ';'		{ $$ = mk_stmt (sRETURN, $2, NULL,
122 							NULL, NULL); }
123 	| tSUB tSYMBOL '(' symbol_list ')' '{' locals stmt_list '}'
124 					{ $$ = mk_stmt (sDEFSUB, $2,
125 							cons (cons ($4, $7),
126 							      $8),
127 							NULL, NULL); }
128 	| '{' stmt_list '}'		{ $$ = mk_stmt (sBLOCK, $2, NULL,
129 							NULL, NULL); }
130 	| tIF '(' expr ')' stmt		{ $$ = mk_stmt (sIF, $3, $5, NULL,
131 							NULL); }
132 	| tIF '(' expr ')' stmt tELSE stmt
133 					{ $$ = mk_stmt (sIF, $3, $5, $7,
134 							NULL); }
135 	| tWHILE '(' expr ')' stmt 	{ $$ = mk_stmt (sWHILE, $3, $5,
136 							NULL, NULL); }
137 	| tFOR '(' cond_expr ';' expr ';' cond_expr ')' stmt
138 					{ $$ = mk_stmt (sFOR, $3, $5, $7,
139 							$9); }
140 	| expr ';'			{ $$ = mk_stmt (sEXPR, $1, NULL,
141 							NULL, NULL); }
142 	;
143 
144 expr	: tSTRING 			{ $$ = mk_expr (eSTRING, $1, NULL,
145 							NULL); }
146 	| tREGEXP			{ $$ = mk_expr (eREGEXP, $1, NULL,
147 							NULL); }
148 	| tINTEGER			{ $$ = mk_expr (eINTEGER, $1, NULL,
149 							NULL); }
150 	| tREAL				{ $$ = mk_expr (eREAL, $1, NULL,
151 							NULL); }
152 	| tSYMBOL			{ $$ = mk_expr (eSYMBOL, $1, NULL,
153 							NULL); }
154 	| '!' expr			{ $$ = mk_expr (eNOT, $2, NULL,
155 							NULL); }
156 	| expr tAND expr		{ $$ = mk_expr (eAND, $1, $3, NULL); }
157 	| expr tOR expr			{ $$ = mk_expr (eOR, $1, $3, NULL); }
158 	| tSYMBOL '(' expr_list ')'	{ $$ = mk_expr (eFCALL, $1, $3,
159 							NULL); }
160 	| tSYMBOL '=' expr		{ $$ = mk_expr (eASSIGN, $1, $3,
161 							NULL); }
162 	| tSYMBOL tADDASSIGN expr	{ $$ = mk_expr (eADDASSIGN, $1, $3,
163 							NULL); }
164 	| tSYMBOL tSUBASSIGN expr	{ $$ = mk_expr (eSUBASSIGN, $1, $3,
165 							NULL); }
166 	| tSYMBOL tMULASSIGN expr	{ $$ = mk_expr (eMULASSIGN, $1, $3,
167 							NULL); }
168 	| tSYMBOL tDIVASSIGN expr	{ $$ = mk_expr (eDIVASSIGN, $1, $3,
169 							NULL); }
170 	| tSYMBOL tPLUSPLUS		{ $$ = mk_expr (ePOSTFIXADD, $1, NULL,
171 							NULL); }
172 	| tSYMBOL tMINUSMINUS		{ $$ = mk_expr (ePOSTFIXSUB, $1, NULL,
173 							NULL); }
174 	| tPLUSPLUS tSYMBOL		{ $$ = mk_expr (ePREFIXADD, $2, NULL,
175 							NULL); }
176 	| tMINUSMINUS tSYMBOL		{ $$ = mk_expr (ePREFIXSUB, $2, NULL,
177 							NULL); }
178 	| expr '[' expr ']' '=' expr	{ $$ = mk_expr (eARRAYASSIGN, $1, $3,
179 							$6); }
180 	| '(' expr ')'			{ $$ = $2; }
181 	| expr '[' expr ']'		{ $$ = mk_expr (eARRAYREF, $1, $3,
182 							NULL); }
183 	| expr '?' expr ':' expr	{ $$ = mk_expr (eQUESTCOLON, $1, $3,
184 							$5); }
185 	| expr '*' expr			{ $$ = mk_expr (eMULT, $1, $3, NULL); }
186 	| expr tDIV expr		{ $$ = mk_expr (eDIV, $1, $3, NULL); }
187 	| expr '+' expr			{ $$ = mk_expr (ePLUS, $1, $3, NULL); }
188 	| expr '-' expr			{ $$ = mk_expr (eMINUS, $1, $3,
189 							NULL); }
190 	| expr '<' expr			{ $$ = mk_expr (eLT, $1, $3, NULL); }
191 	| expr '>' expr			{ $$ = mk_expr (eGT, $1, $3, NULL); }
192 	| expr tEQ expr			{ $$ = mk_expr (eEQ, $1, $3, NULL); }
193 	| expr tNE expr			{ $$ = mk_expr (eNE, $1, $3, NULL); }
194 	| expr tGE expr			{ $$ = mk_expr (eGE, $1, $3, NULL); }
195 	| expr tLE expr			{ $$ = mk_expr (eLE, $1, $3, NULL); }
196 	;
197 
198 cond_expr : /* empty */			{ $$ = NULL; }
199 	| expr				{ $$ = $1; }
200 	;
201 
202 expr_list : /* empty */ 		{ $$ = list (); }
203 	| rest_expr_list 		{ $$ = $1; }
204 	;
205 
206 rest_expr_list: expr 	 		{ $$ = list (); list_append ($$, $1); }
207 	| rest_expr_list ',' expr  	{ list_append ($1, $3); }
208 	;
209 
210 %%
211 
212 void
yyerror(msg)213 yyerror (msg)
214      char *msg;
215 {
216   fprintf (stderr, "%s:%d: %s\n", yyin_name, linenum, msg);
217 }
218