eqn.y revision 151497
1/* Copyright (C) 1989, 1990, 1991, 1992, 2004 Free Software Foundation, Inc. 2 Written by James Clark (jjc@jclark.com) 3 4This file is part of groff. 5 6groff is free software; you can redistribute it and/or modify it under 7the terms of the GNU General Public License as published by the Free 8Software Foundation; either version 2, or (at your option) any later 9version. 10 11groff is distributed in the hope that it will be useful, but WITHOUT ANY 12WARRANTY; without even the implied warranty of MERCHANTABILITY or 13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14for more details. 15 16You should have received a copy of the GNU General Public License along 17with groff; see the file COPYING. If not, write to the Free Software 18Foundation, 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" 26extern int non_empty_flag; 27int yylex(); 28void 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. 102Consider `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%% 122top: 123 /* empty */ 124 | equation 125 { $1->top_level(); non_empty_flag = 1; } 126 ; 127 128equation: 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 141mark: 142 from_to 143 { $$ = $1; } 144 | MARK mark 145 { $$ = make_mark_box($2); } 146 | LINEUP mark 147 { $$ = make_lineup_box($2); } 148 ; 149 150from_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 163sqrt_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 174script: 175 nonsup 176 { $$ = $1; } 177 | simple SUP script 178 { $$ = make_script_box($1, 0, $3); } 179 ; 180 181nonsup: 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 190simple: 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 259number: 260 text 261 { 262 int n; 263 if (sscanf($1, "%d", &n) == 1) 264 $$ = n; 265 a_delete $1; 266 } 267 ; 268 269pile_element_list: 270 equation 271 { $$ = new pile_box($1); } 272 | pile_element_list ABOVE equation 273 { $1->append($3); $$ = $1; } 274 ; 275 276pile_arg: 277 '{' pile_element_list '}' 278 { $$ = $2; } 279 | number '{' pile_element_list '}' 280 { $3->set_space($1); $$ = $3; } 281 ; 282 283column_list: 284 column 285 { $$ = new matrix_box($1); } 286 | column_list column 287 { $1->append($2); $$ = $1; } 288 ; 289 290column_element_list: 291 equation 292 { $$ = new column($1); } 293 | column_element_list ABOVE equation 294 { $1->append($3); $$ = $1; } 295 ; 296 297column_arg: 298 '{' column_element_list '}' 299 { $$ = $2; } 300 | number '{' column_element_list '}' 301 { $3->set_space($1); $$ = $3; } 302 ; 303 304column: 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 315text: TEXT 316 { $$ = $1; } 317 | QUOTED_TEXT 318 { $$ = $1; } 319 ; 320 321delim: 322 text 323 { $$ = $1; } 324 | '{' 325 { $$ = strsave("{"); } 326 | '}' 327 { $$ = strsave("}"); } 328 ; 329 330%% 331