Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / groff / src / preproc / eqn / eqn.y
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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 %%