1 /* Copyright (C) 1989, 1990, 1991, 1992, 2004 Free Software Foundation, Inc.
2      Written by James Clark (jjc@jclark.com)
3 
4 This file is part of groff.
5 
6 groff is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
10 
11 groff is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License along
17 with groff; see the file COPYING.  If not, write to the Free Software
18 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
19 %{
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 
24 #include "lib.h"
25 #include "box.h"
26 extern int non_empty_flag;
27 int yylex();
28 void yyerror(const char *);
29 %}
30 
31 %union {
32 	char *str;
33 	box *b;
34 	pile_box *pb;
35 	matrix_box *mb;
36 	int n;
37 	column *col;
38 }
39 
40 %token OVER
41 %token SMALLOVER
42 %token SQRT
43 %token SUB
44 %token SUP
45 %token LPILE
46 %token RPILE
47 %token CPILE
48 %token PILE
49 %token LEFT
50 %token RIGHT
51 %token TO
52 %token FROM
53 %token SIZE
54 %token FONT
55 %token ROMAN
56 %token BOLD
57 %token ITALIC
58 %token FAT
59 %token ACCENT
60 %token BAR
61 %token UNDER
62 %token ABOVE
63 %token <str> TEXT
64 %token <str> QUOTED_TEXT
65 %token FWD
66 %token BACK
67 %token DOWN
68 %token UP
69 %token MATRIX
70 %token COL
71 %token LCOL
72 %token RCOL
73 %token CCOL
74 %token MARK
75 %token LINEUP
76 %token TYPE
77 %token VCENTER
78 %token PRIME
79 %token SPLIT
80 %token NOSPLIT
81 %token UACCENT
82 %token SPECIAL
83 
84 /* these are handled in the lexer */
85 %token SPACE
86 %token GFONT
87 %token GSIZE
88 %token DEFINE
89 %token NDEFINE
90 %token TDEFINE
91 %token SDEFINE
92 %token UNDEF
93 %token IFDEF
94 %token INCLUDE
95 %token DELIM
96 %token CHARTYPE
97 %token SET
98 %token GRFONT
99 %token GBFONT
100 
101 /* The original eqn manual says that `left' is right associative. It's lying.
102 Consider `left ( ~ left ( ~ right ) right )'. */
103 
104 %right LEFT
105 %left RIGHT
106 %right LPILE RPILE CPILE PILE TEXT QUOTED_TEXT MATRIX MARK LINEUP '^' '~' '\t' '{' SPLIT NOSPLIT
107 %right FROM TO
108 %left SQRT OVER SMALLOVER
109 %right SUB SUP
110 %right ROMAN BOLD ITALIC FAT FONT SIZE FWD BACK DOWN UP TYPE VCENTER SPECIAL
111 %right BAR UNDER PRIME
112 %left ACCENT UACCENT
113 
114 %type <b> mark from_to sqrt_over script simple equation nonsup
115 %type <n> number
116 %type <str> text delim
117 %type <pb> pile_element_list pile_arg
118 %type <mb> column_list
119 %type <col> column column_arg column_element_list
120 
121 %%
122 top:
123 	/* empty */
124 	| equation
125 		{ $1->top_level(); non_empty_flag = 1; }
126 	;
127 
128 equation:
129 	mark
130 		{ $$ = $1; }
131 	| equation mark
132 		{
133 		  list_box *lb = $1->to_list_box();
134 		  if (!lb)
135 		    lb = new list_box($1);
136 		  lb->append($2);
137 		  $$ = lb;
138 		}
139 	;
140 
141 mark:
142 	from_to
143 		{ $$ = $1; }
144 	| MARK mark
145 		{ $$ = make_mark_box($2); }
146 	| LINEUP mark
147 		{ $$ = make_lineup_box($2); }
148 	;
149 
150 from_to:
151 	sqrt_over  %prec FROM
152 		{ $$ = $1; }
153 	| sqrt_over TO from_to
154 		{ $$ = make_limit_box($1, 0, $3); }
155 	| sqrt_over FROM sqrt_over
156 		{ $$ = make_limit_box($1, $3, 0); }
157 	| sqrt_over FROM sqrt_over TO from_to
158 		{ $$ = make_limit_box($1, $3, $5); }
159 	| sqrt_over FROM sqrt_over FROM from_to
160 		{ $$ = make_limit_box($1, make_limit_box($3, $5, 0), 0); }
161 	;
162 
163 sqrt_over:
164 	script
165 		{ $$ = $1; }
166 	| SQRT sqrt_over
167 		{ $$ = make_sqrt_box($2); }
168 	| sqrt_over OVER sqrt_over
169 		{ $$ = make_over_box($1, $3); }
170 	| sqrt_over SMALLOVER sqrt_over
171 		{ $$ = make_small_over_box($1, $3); }
172 	;
173 
174 script:
175 	nonsup
176 		{ $$ = $1; }
177 	| simple SUP script
178 		{ $$ = make_script_box($1, 0, $3); }
179 	;
180 
181 nonsup:
182 	simple  %prec SUP
183 		{ $$ = $1; }
184 	| simple SUB nonsup
185 		{ $$ = make_script_box($1, $3, 0); }
186 	| simple SUB simple SUP script
187 		{ $$ = make_script_box($1, $3, $5); }
188 	;
189 
190 simple:
191 	TEXT
192 		{ $$ = split_text($1); }
193 	| QUOTED_TEXT
194 		{ $$ = new quoted_text_box($1); }
195 	| SPLIT QUOTED_TEXT
196 		{ $$ = split_text($2); }
197 	| NOSPLIT TEXT
198 		{ $$ = new quoted_text_box($2); }
199 	| '^'
200 		{ $$ = new half_space_box; }
201 	| '~'
202 		{ $$ = new space_box; }
203 	| '\t'
204 		{ $$ = new tab_box; }
205 	| '{' equation '}'
206 		{ $$ = $2; }
207 	| PILE pile_arg
208 		{ $2->set_alignment(CENTER_ALIGN); $$ = $2; }
209 	| LPILE pile_arg
210 		{ $2->set_alignment(LEFT_ALIGN); $$ = $2; }
211 	| RPILE pile_arg
212 		{ $2->set_alignment(RIGHT_ALIGN); $$ = $2; }
213 	| CPILE pile_arg
214 		{ $2->set_alignment(CENTER_ALIGN); $$ = $2; }
215 	| MATRIX '{' column_list '}'
216 		{ $$ = $3; }
217 	| LEFT delim equation RIGHT delim
218 		{ $$ = make_delim_box($2, $3, $5); }
219 	| LEFT delim equation
220 		{ $$ = make_delim_box($2, $3, 0); }
221 	| simple BAR
222 		{ $$ = make_overline_box($1); }
223 	| simple UNDER
224 		{ $$ = make_underline_box($1); }
225 	| simple PRIME
226 		{ $$ = make_prime_box($1); }
227 	| simple ACCENT simple
228 		{ $$ = make_accent_box($1, $3); }
229 	| simple UACCENT simple
230 		{ $$ = make_uaccent_box($1, $3); }
231 	| ROMAN simple
232 		{ $$ = new font_box(strsave(get_grfont()), $2); }
233 	| BOLD simple
234 		{ $$ = new font_box(strsave(get_gbfont()), $2); }
235 	| ITALIC simple
236 		{ $$ = new font_box(strsave(get_gfont()), $2); }
237 	| FAT simple
238 		{ $$ = new fat_box($2); }
239 	| FONT text simple
240 		{ $$ = new font_box($2, $3); }
241 	| SIZE text simple
242 		{ $$ = new size_box($2, $3); }
243 	| FWD number simple
244 		{ $$ = new hmotion_box($2, $3); }
245 	| BACK number simple
246 		{ $$ = new hmotion_box(-$2, $3); }
247 	| UP number simple
248 		{ $$ = new vmotion_box($2, $3); }
249 	| DOWN number simple
250 		{ $$ = new vmotion_box(-$2, $3); }
251 	| TYPE text simple
252 		{ $3->set_spacing_type($2); $$ = $3; }
253 	| VCENTER simple
254 		{ $$ = new vcenter_box($2); }
255 	| SPECIAL text simple
256 		{ $$ = make_special_box($2, $3); }
257 	;
258 
259 number:
260 	text
261 		{
262 		  int n;
263 		  if (sscanf($1, "%d", &n) == 1)
264 		    $$ = n;
265 		  a_delete $1;
266 		}
267 	;
268 
269 pile_element_list:
270 	equation
271 		{ $$ = new pile_box($1); }
272 	| pile_element_list ABOVE equation
273 		{ $1->append($3); $$ = $1; }
274 	;
275 
276 pile_arg:
277   	'{' pile_element_list '}'
278 		{ $$ = $2; }
279 	| number '{' pile_element_list '}'
280 		{ $3->set_space($1); $$ = $3; }
281 	;
282 
283 column_list:
284 	column
285 		{ $$ = new matrix_box($1); }
286 	| column_list column
287 		{ $1->append($2); $$ = $1; }
288 	;
289 
290 column_element_list:
291 	equation
292 		{ $$ = new column($1); }
293 	| column_element_list ABOVE equation
294 		{ $1->append($3); $$ = $1; }
295 	;
296 
297 column_arg:
298   	'{' column_element_list '}'
299 		{ $$ = $2; }
300 	| number '{' column_element_list '}'
301 		{ $3->set_space($1); $$ = $3; }
302 	;
303 
304 column:
305 	COL column_arg
306 		{ $2->set_alignment(CENTER_ALIGN); $$ = $2; }
307 	| LCOL column_arg
308 		{ $2->set_alignment(LEFT_ALIGN); $$ = $2; }
309 	| RCOL column_arg
310 		{ $2->set_alignment(RIGHT_ALIGN); $$ = $2; }
311 	| CCOL column_arg
312 		{ $2->set_alignment(CENTER_ALIGN); $$ = $2; }
313 	;
314 
315 text:	TEXT
316 		{ $$ = $1; }
317 	| QUOTED_TEXT
318 		{ $$ = $1; }
319 	;
320 
321 delim:
322 	text
323 		{ $$ = $1; }
324 	| '{'
325 		{ $$ = strsave("{"); }
326 	| '}'
327 		{ $$ = strsave("}"); }
328 	;
329 
330 %%
331