xref: /386bsd/usr/src/usr.bin/groff/eqn/eqn.y (revision a2142627)
1 /* Copyright (C) 1989, 1990, 1991, 1992 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, 675 Mass Ave, Cambridge, MA 02139, 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 char *strsave(const char *);
28 int yylex();
29 void yyerror(const char *);
30 %}
31 
32 %union {
33 	char *str;
34 	box *b;
35 	pile_box *pb;
36 	matrix_box *mb;
37 	int n;
38 	column *col;
39 }
40 
41 %token OVER
42 %token SMALLOVER
43 %token SQRT
44 %token SUB
45 %token SUP
46 %token LPILE
47 %token RPILE
48 %token CPILE
49 %token PILE
50 %token LEFT
51 %token RIGHT
52 %token TO
53 %token FROM
54 %token SIZE
55 %token FONT
56 %token ROMAN
57 %token BOLD
58 %token ITALIC
59 %token FAT
60 %token ACCENT
61 %token BAR
62 %token UNDER
63 %token ABOVE
64 %token <str> TEXT
65 %token <str> QUOTED_TEXT
66 %token FWD
67 %token BACK
68 %token DOWN
69 %token UP
70 %token MATRIX
71 %token COL
72 %token LCOL
73 %token RCOL
74 %token CCOL
75 %token MARK
76 %token LINEUP
77 %token TYPE
78 %token VCENTER
79 %token PRIME
80 %token SPLIT
81 %token NOSPLIT
82 %token UACCENT
83 %token SPECIAL
84 
85 /* these are handled in the lexer */
86 %token SPACE
87 %token GFONT
88 %token GSIZE
89 %token DEFINE
90 %token NDEFINE
91 %token TDEFINE
92 %token SDEFINE
93 %token UNDEF
94 %token IFDEF
95 %token INCLUDE
96 %token DELIM
97 %token CHARTYPE
98 %token SET
99 %token GRFONT
100 %token GBFONT
101 
102 /* The original eqn manual says that `left' is right associative. It's lying.
103 Consider `left ( ~ left ( ~ right ) right )'. */
104 
105 %right LEFT
106 %left RIGHT
107 %right LPILE RPILE CPILE PILE TEXT QUOTED_TEXT MATRIX MARK LINEUP '^' '~' '\t' '{' SPLIT NOSPLIT
108 %right FROM TO
109 %left SQRT OVER SMALLOVER
110 %right SUB SUP
111 %right ROMAN BOLD ITALIC FAT FONT SIZE FWD BACK DOWN UP TYPE VCENTER SPECIAL
112 %right BAR UNDER PRIME
113 %left ACCENT UACCENT
114 
115 %type <b> mark from_to sqrt_over script simple equation nonsup
116 %type <n> number
117 %type <str> text delim
118 %type <pb> pile_element_list pile_arg
119 %type <mb> column_list
120 %type <col> column column_arg column_element_list
121 
122 %%
123 top:
124 	/* empty */
125 	| equation
126 		{ $1->top_level(); non_empty_flag = 1; }
127 	;
128 
129 equation:
130 	mark
131 		{ $$ = $1; }
132 	| equation mark
133 		{
134 		  list_box *lb = $1->to_list_box();
135 		  if (!lb)
136 		    lb = new list_box($1);
137 		  lb->append($2);
138 		  $$ = lb;
139 		}
140 	;
141 
142 mark:
143 	from_to
144 		{ $$ = $1; }
145 	| MARK mark
146 		{ $$ = make_mark_box($2); }
147 	| LINEUP mark
148 		{ $$ = make_lineup_box($2); }
149 	;
150 
151 from_to:
152 	sqrt_over  %prec FROM
153 		{ $$ = $1; }
154 	| sqrt_over TO from_to
155 		{ $$ = make_limit_box($1, 0, $3); }
156 	| sqrt_over FROM sqrt_over
157 		{ $$ = make_limit_box($1, $3, 0); }
158 	| sqrt_over FROM sqrt_over TO from_to
159 		{ $$ = make_limit_box($1, $3, $5); }
160 	| sqrt_over FROM sqrt_over FROM from_to
161 		{ $$ = make_limit_box($1, make_limit_box($3, $5, 0), 0); }
162 	;
163 
164 sqrt_over:
165 	script
166 		{ $$ = $1; }
167 	| SQRT sqrt_over
168 		{ $$ = make_sqrt_box($2); }
169 	| sqrt_over OVER sqrt_over
170 		{ $$ = make_over_box($1, $3); }
171 	| sqrt_over SMALLOVER sqrt_over
172 		{ $$ = make_small_over_box($1, $3); }
173 	;
174 
175 script:
176 	nonsup
177 		{ $$ = $1; }
178 	| simple SUP script
179 		{ $$ = make_script_box($1, 0, $3); }
180 	;
181 
182 nonsup:
183 	simple  %prec SUP
184 		{ $$ = $1; }
185 	| simple SUB nonsup
186 		{ $$ = make_script_box($1, $3, 0); }
187 	| simple SUB simple SUP script
188 		{ $$ = make_script_box($1, $3, $5); }
189 	;
190 
191 simple:
192 	TEXT
193 		{ $$ = split_text($1); }
194 	| QUOTED_TEXT
195 		{ $$ = new quoted_text_box($1); }
196 	| SPLIT QUOTED_TEXT
197 		{ $$ = split_text($2); }
198 	| NOSPLIT TEXT
199 		{ $$ = new quoted_text_box($2); }
200 	| '^'
201 		{ $$ = new half_space_box; }
202 	| '~'
203 		{ $$ = new space_box; }
204 	| '\t'
205 		{ $$ = new tab_box; }
206 	| '{' equation '}'
207 		{ $$ = $2; }
208 	| PILE pile_arg
209 		{ $2->set_alignment(CENTER_ALIGN); $$ = $2; }
210 	| LPILE pile_arg
211 		{ $2->set_alignment(LEFT_ALIGN); $$ = $2; }
212 	| RPILE pile_arg
213 		{ $2->set_alignment(RIGHT_ALIGN); $$ = $2; }
214 	| CPILE pile_arg
215 		{ $2->set_alignment(CENTER_ALIGN); $$ = $2; }
216 	| MATRIX '{' column_list '}'
217 		{ $$ = $3; }
218 	| LEFT delim equation RIGHT delim
219 		{ $$ = make_delim_box($2, $3, $5); }
220 	| LEFT delim equation
221 		{ $$ = make_delim_box($2, $3, 0); }
222 	| simple BAR
223 		{ $$ = make_overline_box($1); }
224 	| simple UNDER
225 		{ $$ = make_underline_box($1); }
226 	| simple PRIME
227 		{ $$ = make_prime_box($1); }
228 	| simple ACCENT simple
229 		{ $$ = make_accent_box($1, $3); }
230 	| simple UACCENT simple
231 		{ $$ = make_uaccent_box($1, $3); }
232 	| ROMAN simple
233 		{ $$ = new font_box(strsave(get_grfont()), $2); }
234 	| BOLD simple
235 		{ $$ = new font_box(strsave(get_gbfont()), $2); }
236 	| ITALIC simple
237 		{ $$ = new font_box(strsave(get_gfont()), $2); }
238 	| FAT simple
239 		{ $$ = new fat_box($2); }
240 	| FONT text simple
241 		{ $$ = new font_box($2, $3); }
242 	| SIZE text simple
243 		{ $$ = new size_box($2, $3); }
244 	| FWD number simple
245 		{ $$ = new hmotion_box($2, $3); }
246 	| BACK number simple
247 		{ $$ = new hmotion_box(-$2, $3); }
248 	| UP number simple
249 		{ $$ = new vmotion_box($2, $3); }
250 	| DOWN number simple
251 		{ $$ = new vmotion_box(-$2, $3); }
252 	| TYPE text simple
253 		{ $3->set_spacing_type($2); $$ = $3; }
254 	| VCENTER simple
255 		{ $$ = new vcenter_box($2); }
256 	| SPECIAL text simple
257 		{ $$ = make_special_box($2, $3); }
258 	;
259 
260 number:
261 	text
262 		{
263 		  int n;
264 		  if (sscanf($1, "%d", &n) == 1)
265 		    $$ = n;
266 		  a_delete $1;
267 		}
268 	;
269 
270 pile_element_list:
271 	equation
272 		{ $$ = new pile_box($1); }
273 	| pile_element_list ABOVE equation
274 		{ $1->append($3); $$ = $1; }
275 	;
276 
277 pile_arg:
278   	'{' pile_element_list '}'
279 		{ $$ = $2; }
280 	| number '{' pile_element_list '}'
281 		{ $3->set_space($1); $$ = $3; }
282 	;
283 
284 column_list:
285 	column
286 		{ $$ = new matrix_box($1); }
287 	| column_list column
288 		{ $1->append($2); $$ = $1; }
289 	;
290 
291 column_element_list:
292 	equation
293 		{ $$ = new column($1); }
294 	| column_element_list ABOVE equation
295 		{ $1->append($3); $$ = $1; }
296 	;
297 
298 column_arg:
299   	'{' column_element_list '}'
300 		{ $$ = $2; }
301 	| number '{' column_element_list '}'
302 		{ $3->set_space($1); $$ = $3; }
303 	;
304 
305 column:
306 	COL column_arg
307 		{ $2->set_alignment(CENTER_ALIGN); $$ = $2; }
308 	| LCOL column_arg
309 		{ $2->set_alignment(LEFT_ALIGN); $$ = $2; }
310 	| RCOL column_arg
311 		{ $2->set_alignment(RIGHT_ALIGN); $$ = $2; }
312 	| CCOL column_arg
313 		{ $2->set_alignment(CENTER_ALIGN); $$ = $2; }
314 	;
315 
316 text:	TEXT
317 		{ $$ = $1; }
318 	| QUOTED_TEXT
319 		{ $$ = $1; }
320 	;
321 
322 delim:
323 	text
324 		{ $$ = $1; }
325 	| '{'
326 		{ $$ = strsave("{"); }
327 	| '}'
328 		{ $$ = strsave("}"); }
329 	;
330 
331 %%
332