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