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