1 /* rtfGrammer.y 2 3 Copyright (C) 1999 Free Software Foundation, Inc. 4 5 Author: Stefan B�hringer (stefan.boehringer@uni-bochum.de) 6 Date: Dec 1999 7 8 This file is part of the GNUstep GUI Library. 9 10 This library is free software; you can redistribute it and/or 11 modify it under the terms of the GNU Lesser General Public 12 License as published by the Free Software Foundation; either 13 version 2 of the License, or (at your option) any later version. 14 15 This library is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 Lesser General Public License for more details. 19 20 You should have received a copy of the GNU Lesser General Public 21 License along with this library; see the file COPYING.LIB. 22 If not, see <http://www.gnu.org/licenses/> or write to the 23 Free Software Foundation, 51 Franklin Street, Fifth Floor, 24 Boston, MA 02110-1301, USA. 25 */ 26 27 /* 28 if processed using -p GSRTFP (as recommended) it will introduce the following global symbols: 29 'GSRTFPparse', `GSRTFPlex', `GSRTFPerror', `GSRTFPnerrs', `GSRTFPlval', 30 `GSRTFPchar', `GSRTFPdebug 31 */ 32 33 /* we request for a reentrant parser */ 34 %define api.pure 35 36 %{ 37 38 /* 39 The overall plan is to make this grammer universal in usage. 40 Intrested buddies can implement plain C functions to consume what 41 the grammer is producing. this way the rtf-grammer-tree can be 42 converted to what is needed: GNUstep attributed strings, tex files, 43 ... 44 45 The plan is laid out by defining a set of C functions which cover 46 all what is needed to mangle rtf information (it is NeXT centric 47 however and may even lack some features). Be aware that some 48 functions are called at specific times when some information may or 49 may not be available. The first argument of all functions is a 50 context, which is asked to be maintained by the consumer at 51 whichever purpose seems appropriate. This context must be passed to 52 the parser by issuing 'value = GSRTFparse(ctxt, lctxt);' in the 53 first place. 54 */ 55 56 #import <AppKit/AppKit.h> 57 #include <stdlib.h> 58 #include <string.h> 59 #include "rtfScanner.h" 60 61 /* this context is passed to the interface functions */ 62 typedef void *GSRTFctxt; 63 /*#undef YYLSP_NEEDED*/ 64 #define CTXT ctxt 65 66 #define YYERROR_VERBOSE 67 #define YYDEBUG 1 68 69 #include "RTFConsumerFunctions.h" 70 /*int GSRTFlex (YYSTYPE *lvalp, RTFscannerCtxt *lctxt); */ 71 int GSRTFlex(void *lvalp, void *lctxt); 72 73 /* */ 74 int fieldStart = 0; 75 76 %} 77 78 %parse-param {void *ctxt} 79 %parse-param {void *lctxt} 80 %lex-param {void *lctxt} 81 82 %union { 83 int number; 84 const char *text; 85 RTFcmd cmd; 86 } 87 88 /* <!><p> RTFtext values have to be freed */ 89 %token <text> RTFtext 90 %token RTFstart 91 %token RTFansi 92 %token RTFmac 93 %token RTFpc 94 %token RTFpca 95 %token RTFignore 96 %token RTFinfo 97 %token RTFstylesheet 98 %token RTFfootnote 99 %token RTFheader 100 %token RTFfooter 101 %token RTFpict 102 %token RTFplain 103 %token RTFparagraph 104 %token RTFdefaultParagraph 105 %token RTFrow 106 %token RTFcell 107 %token RTFtabulator 108 %token RTFemdash 109 %token RTFendash 110 %token RTFemspace 111 %token RTFenspace 112 %token RTFbullet 113 %token RTFfield 114 %token RTFfldinst 115 %token RTFfldalt 116 %token RTFfldrslt 117 %token RTFflddirty 118 %token RTFfldedit 119 %token RTFfldlock 120 %token RTFfldpriv 121 %token RTFfttruetype 122 %token RTFlquote 123 %token RTFrquote 124 %token RTFldblquote 125 %token RTFrdblquote 126 %token <cmd> RTFred 127 %token <cmd> RTFgreen 128 %token <cmd> RTFblue 129 %token <cmd> RTFcolorbg 130 %token <cmd> RTFcolorfg 131 %token <cmd> RTFunderlinecolor 132 %token <cmd> RTFcolortable 133 %token <cmd> RTFfont 134 %token <cmd> RTFfontSize 135 %token <cmd> RTFNeXTGraphic 136 %token <cmd> RTFNeXTGraphicWidth 137 %token <cmd> RTFNeXTGraphicHeight 138 %token <cmd> RTFNeXTHelpLink 139 %token <cmd> RTFNeXTHelpMarker 140 %token <cmd> RTFNeXTfilename 141 %token <cmd> RTFNeXTmarkername 142 %token <cmd> RTFNeXTlinkFilename 143 %token <cmd> RTFNeXTlinkMarkername 144 %token <cmd> RTFpaperWidth 145 %token <cmd> RTFpaperHeight 146 %token <cmd> RTFmarginLeft 147 %token <cmd> RTFmarginRight 148 %token <cmd> RTFmarginTop 149 %token <cmd> RTFmarginButtom 150 %token <cmd> RTFfirstLineIndent 151 %token <cmd> RTFleftIndent 152 %token <cmd> RTFrightIndent 153 %token <cmd> RTFalignCenter 154 %token <cmd> RTFalignJustified 155 %token <cmd> RTFalignLeft 156 %token <cmd> RTFalignRight 157 %token <cmd> RTFlineSpace 158 %token <cmd> RTFspaceAbove 159 %token <cmd> RTFstyle 160 %token <cmd> RTFbold 161 %token <cmd> RTFitalic 162 %token <cmd> RTFunderline 163 %token <cmd> RTFunderlineDot 164 %token <cmd> RTFunderlineDash 165 %token <cmd> RTFunderlineDashDot 166 %token <cmd> RTFunderlineDashDotDot 167 %token <cmd> RTFunderlineDouble 168 %token <cmd> RTFunderlineStop 169 %token <cmd> RTFunderlineThick 170 %token <cmd> RTFunderlineThickDot 171 %token <cmd> RTFunderlineThickDash 172 %token <cmd> RTFunderlineThickDashDot 173 %token <cmd> RTFunderlineThickDashDotDot 174 %token <cmd> RTFunderlineWord 175 %token <cmd> RTFstrikethrough 176 %token <cmd> RTFstrikethroughDouble 177 %token <cmd> RTFunichar 178 %token <cmd> RTFsubscript 179 %token <cmd> RTFsuperscript 180 %token <cmd> RTFtabstop 181 %token <cmd> RTFfcharset 182 %token <cmd> RTFfprq 183 %token <cmd> RTFcpg 184 %token <cmd> RTFansicpg 185 %token <cmd> RTFOtherStatement 186 %token RTFfontListStart 187 188 // <!> we assume token numbers to be sequential 189 // \fnil | \froman | \fswiss | \fmodern | \fscript | \fdecor | \ftech 190 // look at rtfScanner.h for enum definition 191 %token RTFfamilyNil 192 %token RTFfamilyRoman 193 %token RTFfamilySwiss 194 %token RTFfamilyModern 195 %token RTFfamilyScript 196 %token RTFfamilyDecor 197 %token RTFfamilyTech 198 %token RTFfamilyBiDi 199 200 %type <number> rtfFontFamily rtfCharset rtfFontStatement 201 %type <text> rtfFieldinst 202 203 /* let's go */ 204 205 %% 206 207 rtfFile: '{' { GSRTFstart(CTXT); } RTFstart rtfIngredients { GSRTFstop(CTXT); } '}' 208 ; 209 210 rtfCharset: RTFansi { GSRTFencoding(CTXT, 1); } 211 | RTFmac { GSRTFencoding(CTXT, 2); } 212 | RTFpc { GSRTFencoding(CTXT, $$ = 3); } 213 | RTFpca { GSRTFencoding(CTXT, 4); } 214 | rtfCharset RTFansicpg { GSRTFencoding(CTXT, $2.parameter); } 215 ; 216 217 rtfIngredients: /* empty */ 218 | rtfIngredients rtfCharset 219 | rtfIngredients rtfFontList 220 | rtfIngredients rtfColorDef 221 | rtfIngredients rtfStatement 222 | rtfIngredients RTFtext { GSRTFmangleText(CTXT, $2); free((void *)$2); } 223 | rtfIngredients rtfBlock 224 | rtfIngredients error 225 ; 226 227 rtfBlock: '{' { GSRTFopenBlock(CTXT, NO); } rtfIngredients rtfNeXTstuff '}' { GSRTFcloseBlock(CTXT, NO); } /* may be empty */ 228 | '{' { GSRTFopenBlock(CTXT, YES); } RTFignore rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); } 229 | '{' { GSRTFopenBlock(CTXT, YES); } RTFinfo rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); } 230 | '{' { GSRTFopenBlock(CTXT, YES); } RTFstylesheet rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); } 231 | '{' { GSRTFopenBlock(CTXT, YES); } RTFfootnote rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); } 232 | '{' { GSRTFopenBlock(CTXT, YES); } RTFheader rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); } 233 | '{' { GSRTFopenBlock(CTXT, YES); } RTFfooter rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); } 234 | '{' { GSRTFopenBlock(CTXT, YES); } RTFpict rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); } 235 | '{' { GSRTFopenBlock(CTXT, NO); } RTFfield rtfField '}' { GSRTFcloseBlock(CTXT, NO); } 236 | '{' error '}' 237 ; 238 239 240 rtfField: { fieldStart = GSRTFgetPosition(CTXT);} rtfFieldMod rtfFieldinst rtfFieldrslt { GSRTFaddField(CTXT, fieldStart, $3); free((void *)$3); } 241 | error 242 ; 243 244 rtfFieldMod: /* empty */ 245 | rtfFieldMod RTFflddirty 246 | rtfFieldMod RTFfldedit 247 | rtfFieldMod RTFfldlock 248 | rtfFieldMod RTFfldpriv 249 ; 250 251 rtfIgnore: /* empty */ 252 | RTFignore 253 ; 254 255 rtfFieldinst: '{' rtfIgnore RTFfldinst RTFtext rtfFieldalt '}' { $$ = $4;} 256 | '{' rtfIgnore RTFfldinst '{' { GSRTFopenBlock(CTXT, YES); } rtfStatementList RTFtext rtfFieldalt '}' { GSRTFcloseBlock(CTXT, YES); } '}' { $$ = $7;} 257 | '{' error '}' { $$ = NULL;} 258 ; 259 260 rtfFieldalt: /* empty */ 261 | RTFfldalt 262 ; 263 264 rtfFieldrslt: '{' rtfIgnore RTFfldrslt rtfIngredients '}' 265 | '{' error '}' 266 ; 267 268 rtfStatementList: /* empty */ 269 | rtfStatementList rtfStatement 270 | rtfStatementList rtfBlock 271 ; 272 273 /* 274 RTF statements start with a '\', have a alpha name and a number argument 275 */ 276 277 rtfStatement: RTFfont { int font; 278 279 if ($1.isEmpty) 280 font = 0; 281 else 282 font = $1.parameter; 283 GSRTFfontNumber(CTXT, font); } 284 | RTFfontSize { int size; 285 286 if ($1.isEmpty) 287 size = 24; 288 else 289 size = $1.parameter; 290 GSRTFfontSize(CTXT, size); } 291 | RTFpaperWidth { int width; 292 293 if ($1.isEmpty) 294 width = 12240; 295 else 296 width = $1.parameter; 297 GSRTFpaperWidth(CTXT, width);} 298 | RTFpaperHeight { int height; 299 300 if ($1.isEmpty) 301 height = 15840; 302 else 303 height = $1.parameter; 304 GSRTFpaperHeight(CTXT, height);} 305 | RTFmarginLeft { int margin; 306 307 if ($1.isEmpty) 308 margin = 1800; 309 else 310 margin = $1.parameter; 311 GSRTFmarginLeft(CTXT, margin);} 312 | RTFmarginRight { int margin; 313 314 if ($1.isEmpty) 315 margin = 1800; 316 else 317 margin = $1.parameter; 318 GSRTFmarginRight(CTXT, margin); } 319 | RTFmarginTop { int margin; 320 321 if ($1.isEmpty) 322 margin = 1440; 323 else 324 margin = $1.parameter; 325 GSRTFmarginTop(CTXT, margin); } 326 | RTFmarginButtom { int margin; 327 328 if ($1.isEmpty) 329 margin = 1440; 330 else 331 margin = $1.parameter; 332 GSRTFmarginButtom(CTXT, margin); } 333 | RTFfirstLineIndent { int indent; 334 335 if ($1.isEmpty) 336 indent = 0; 337 else 338 indent = $1.parameter; 339 GSRTFfirstLineIndent(CTXT, indent); } 340 | RTFleftIndent { int indent; 341 342 if ($1.isEmpty) 343 indent = 0; 344 else 345 indent = $1.parameter; 346 GSRTFleftIndent(CTXT, indent);} 347 | RTFrightIndent { int indent; 348 349 if ($1.isEmpty) 350 indent = 0; 351 else 352 indent = $1.parameter; 353 GSRTFrightIndent(CTXT, indent);} 354 | RTFtabstop { int location; 355 356 if ($1.isEmpty) 357 location = 0; 358 else 359 location = $1.parameter; 360 GSRTFtabstop(CTXT, location);} 361 | RTFalignCenter { GSRTFalignCenter(CTXT); } 362 | RTFalignJustified { GSRTFalignJustified(CTXT); } 363 | RTFalignLeft { GSRTFalignLeft(CTXT); } 364 | RTFalignRight { GSRTFalignRight(CTXT); } 365 | RTFspaceAbove { int space; 366 367 if ($1.isEmpty) 368 space = 0; 369 else 370 space = $1.parameter; 371 GSRTFspaceAbove(CTXT, space); } 372 | RTFlineSpace { GSRTFlineSpace(CTXT, $1.parameter); } 373 | RTFdefaultParagraph { GSRTFdefaultParagraph(CTXT); } 374 | RTFstyle { GSRTFstyle(CTXT, $1.parameter); } 375 | RTFcolorbg { int color; 376 377 if ($1.isEmpty) 378 color = 0; 379 else 380 color = $1.parameter; 381 GSRTFcolorbg(CTXT, color); } 382 | RTFcolorfg { int color; 383 384 if ($1.isEmpty) 385 color = 0; 386 else 387 color = $1.parameter; 388 GSRTFcolorfg(CTXT, color); } 389 | RTFunderlinecolor { int color; 390 391 if ($1.isEmpty) 392 color = 0; 393 else 394 color = $1.parameter; 395 GSRTFunderlinecolor(CTXT, color); } 396 | RTFsubscript { int script; 397 398 if ($1.isEmpty) 399 script = 6; 400 else 401 script = $1.parameter; 402 GSRTFsubscript(CTXT, script); } 403 | RTFsuperscript { int script; 404 405 if ($1.isEmpty) 406 script = 6; 407 else 408 script = $1.parameter; 409 GSRTFsuperscript(CTXT, script); } 410 | RTFbold { BOOL on; 411 412 if ($1.isEmpty || $1.parameter) 413 on = YES; 414 else 415 on = NO; 416 GSRTFbold(CTXT, on); } 417 | RTFitalic { BOOL on; 418 419 if ($1.isEmpty || $1.parameter) 420 on = YES; 421 else 422 on = NO; 423 GSRTFitalic(CTXT, on); } 424 | RTFunderline { BOOL on; 425 426 if ($1.isEmpty || $1.parameter) 427 on = YES; 428 else 429 on = NO; 430 GSRTFunderline(CTXT, on, NSUnderlineStyleSingle | NSUnderlinePatternSolid); } 431 | RTFunderlineDot { BOOL on; 432 433 if ($1.isEmpty || $1.parameter) 434 on = YES; 435 else 436 on = NO; 437 GSRTFunderline(CTXT, on, NSUnderlineStyleSingle | NSUnderlinePatternDot); } 438 | RTFunderlineDash { BOOL on; 439 440 if ($1.isEmpty || $1.parameter) 441 on = YES; 442 else 443 on = NO; 444 GSRTFunderline(CTXT, on, NSUnderlineStyleSingle | NSUnderlinePatternDash); } 445 | RTFunderlineDashDot { BOOL on; 446 447 if ($1.isEmpty || $1.parameter) 448 on = YES; 449 else 450 on = NO; 451 GSRTFunderline(CTXT, on, NSUnderlineStyleSingle | NSUnderlinePatternDashDot); } 452 | RTFunderlineDashDotDot { BOOL on; 453 454 if ($1.isEmpty || $1.parameter) 455 on = YES; 456 else 457 on = NO; 458 GSRTFunderline(CTXT, on, NSUnderlineStyleSingle | NSUnderlinePatternDashDotDot); } 459 | RTFunderlineDouble { BOOL on; 460 461 if ($1.isEmpty || $1.parameter) 462 on = YES; 463 else 464 on = NO; 465 GSRTFunderline(CTXT, on, NSUnderlineStyleDouble | NSUnderlinePatternSolid); } 466 | RTFunderlineStop { GSRTFunderline(CTXT, NO, NSUnderlineStyleNone); } 467 | RTFunderlineThick { BOOL on; 468 469 if ($1.isEmpty || $1.parameter) 470 on = YES; 471 else 472 on = NO; 473 GSRTFunderline(CTXT, on, NSUnderlineStyleThick | NSUnderlinePatternSolid); } 474 | RTFunderlineThickDot { BOOL on; 475 476 if ($1.isEmpty || $1.parameter) 477 on = YES; 478 else 479 on = NO; 480 GSRTFunderline(CTXT, on, NSUnderlineStyleThick | NSUnderlinePatternDot); } 481 | RTFunderlineThickDash { BOOL on; 482 483 if ($1.isEmpty || $1.parameter) 484 on = YES; 485 else 486 on = NO; 487 GSRTFunderline(CTXT, on, NSUnderlineStyleThick | NSUnderlinePatternDash); } 488 | RTFunderlineThickDashDot { BOOL on; 489 490 if ($1.isEmpty || $1.parameter) 491 on = YES; 492 else 493 on = NO; 494 GSRTFunderline(CTXT, on, NSUnderlineStyleThick | NSUnderlinePatternDashDot); } 495 | RTFunderlineThickDashDotDot { BOOL on; 496 497 if ($1.isEmpty || $1.parameter) 498 on = YES; 499 else 500 on = NO; 501 GSRTFunderline(CTXT, on, NSUnderlineStyleThick | NSUnderlinePatternDashDotDot); } 502 | RTFunderlineWord { BOOL on; 503 504 if ($1.isEmpty || $1.parameter) 505 on = YES; 506 else 507 on = NO; 508 GSRTFunderline(CTXT, on, NSUnderlineStyleSingle | NSUnderlinePatternSolid | NSUnderlineByWordMask); } 509 | RTFstrikethrough { NSInteger style; 510 if ($1.isEmpty || $1.parameter) 511 style = NSUnderlineStyleSingle | NSUnderlinePatternSolid; 512 else 513 style = NSUnderlineStyleNone; 514 GSRTFstrikethrough(CTXT, style); } 515 | RTFstrikethroughDouble { GSRTFstrikethrough(CTXT, NSUnderlineStyleDouble | NSUnderlinePatternSolid); } 516 | RTFunichar { GSRTFunicode(CTXT, $1.parameter); } 517 | RTFplain { GSRTFdefaultCharacterStyle(CTXT); } 518 | RTFparagraph { GSRTFparagraph(CTXT); } 519 | RTFrow { GSRTFparagraph(CTXT); } 520 | RTFOtherStatement { GSRTFgenericRTFcommand(CTXT, $1); 521 free((void*)$1.name); } 522 ; 523 524 rtfNeXTstuff: /* empty */ 525 | rtfNeXTGraphic 526 | rtfNeXTHelpLink 527 | rtfNeXTHelpMarker 528 ; 529 530 /* 531 NeXTGraphic (images) 532 This is a Apple/NeXT extension. The format of the command is 533 {{\NeXTGraphic attachment \widthN \heightN} string} 534 and the string is ignored (on OS X it is always 0xAC). 535 See the Section "RTF Files and Attributed Strings" in Apple's 536 Attributed Strings Programming Guide. 537 */ 538 539 rtfNeXTGraphic: '{' RTFNeXTGraphic RTFtext RTFNeXTGraphicWidth RTFNeXTGraphicHeight '}' { GSRTFopenBlock(CTXT, YES); } rtfIngredients { GSRTFcloseBlock(CTXT, YES); } 540 { 541 GSRTFNeXTGraphic (CTXT, $3, $4.parameter, $5.parameter); 542 }; 543 544 /* 545 NeXTHelpLink 546 This is a NeXT extension. The format of the command is 547 {{\NeXTHelpLinkN \markername markername; \linkFilename filename; 548 \linkMarkername markername;} string} 549 and the string is ignored (it is always 0xAC on NeXT). 550 Note that the {\NeXTHelpLink } group may itself be preceded by 551 other commands. 552 */ 553 554 rtfNeXTHelpLink: '{' RTFNeXTHelpLink RTFNeXTmarkername RTFtext RTFNeXTlinkFilename RTFtext RTFNeXTlinkMarkername RTFtext '}' { GSRTFopenBlock(CTXT, YES); } rtfIngredients { GSRTFcloseBlock(CTXT, YES); } 555 { 556 GSRTFNeXTHelpLink (CTXT, $2.parameter, $4, $6, $8); 557 }; 558 559 /* 560 NeXTHelpMarker 561 This is a NeXT extension. The format of the command is 562 {{\NeXTHelpMarkerN \markername markername;} string} 563 and the string is ignored (it is always 0xAC on NeXT). 564 Note that the {\NeXTHelpLink } group may itself be preceded by 565 other commands. 566 */ 567 568 rtfNeXTHelpMarker: '{' RTFNeXTHelpMarker RTFNeXTmarkername RTFtext '}' { GSRTFopenBlock(CTXT, YES); } rtfIngredients { GSRTFcloseBlock(CTXT, YES); } 569 { 570 GSRTFNeXTHelpMarker (CTXT, $2.parameter, $4); 571 }; 572 573 /* 574 Font description 575 */ 576 577 rtfFontList: '{' RTFfontListStart rtfFonts '}' 578 ; 579 580 rtfFonts: 581 | rtfFonts rtfFontStatement 582 | rtfFonts '{' rtfFontStatement '}' 583 | rtfFonts '{' rtfFontStatement rtfBlock RTFtext '}' 584 { free((void *)$5);} 585 ; 586 587 /* the first RTFfont tags the font with a number */ 588 /* RTFtext introduces the fontName */ 589 rtfFontStatement: RTFfont rtfFontFamily rtfFontAttrs RTFtext { GSRTFregisterFont(CTXT, $4, $2, $1.parameter); 590 free((void *)$4); } 591 /* fbidi should be a font family, but it seems to be used differently */ 592 | RTFfont RTFfamilyBiDi rtfFontFamily rtfFontAttrs RTFtext { GSRTFregisterFont(CTXT, $5, $3, $1.parameter); 593 free((void *)$5); } 594 /* Theme fonts */ 595 | RTFOtherStatement RTFfont RTFfamilyBiDi rtfFontFamily rtfFontAttrs RTFtext { GSRTFregisterFont(CTXT, $6, $4, $2.parameter); 596 free((void *)$6); } 597 ; 598 599 rtfFontAttrs: /* empty */ 600 | rtfFontAttrs RTFfcharset 601 | rtfFontAttrs RTFfprq 602 | rtfFontAttrs RTFcpg 603 | rtfFontAttrs RTFfttruetype 604 | rtfFontAttrs rtfBlock 605 ; 606 607 608 rtfFontFamily: 609 RTFfamilyNil { $$ = RTFfamilyNil - RTFfamilyNil; } 610 | RTFfamilyRoman { $$ = RTFfamilyRoman - RTFfamilyNil; } 611 | RTFfamilySwiss { $$ = RTFfamilySwiss - RTFfamilyNil; } 612 | RTFfamilyModern { $$ = RTFfamilyModern - RTFfamilyNil; } 613 | RTFfamilyScript { $$ = RTFfamilyScript - RTFfamilyNil; } 614 | RTFfamilyDecor { $$ = RTFfamilyDecor - RTFfamilyNil; } 615 | RTFfamilyTech { $$ = RTFfamilyTech - RTFfamilyNil; } 616 ; 617 618 619 /* 620 Colour definition 621 */ 622 623 rtfColorDef: '{' RTFcolortable rtfColors '}' 624 ; 625 626 rtfColors: /* empty */ 627 | rtfColors rtfColorStatement 628 ; 629 630 /* We get the ';' as RTFText */ 631 rtfColorStatement: RTFred RTFgreen RTFblue RTFtext 632 { 633 GSRTFaddColor(CTXT, $1.parameter, $2.parameter, $3.parameter); 634 free((void *)$4); 635 } 636 | RTFtext 637 { 638 GSRTFaddDefaultColor(CTXT); 639 free((void *)$1); 640 } 641 ; 642 643 /* 644 some cludgy trailer 645 dummyNonTerminal: '\\' { @1.first_line; } / * we introduce a @n to fix the lex attributes * / 646 ; 647 */ 648 649 %% 650 651 /* some C code here */ 652 653