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