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