1 # Exercising Bison on actual grammars. -*- Autotest -*-
3 # Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004
4 # Free Software Foundation, Inc.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2, or (at your option)
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 AT_BANNER([[Existing Grammars.]])
22 ## ----------------- ##
23 ## GNU AWK Grammar. ##
24 ## ----------------- ##
26 AT_SETUP([GNU AWK Grammar])
28 # We have been careful to strip all the actions excepts the
29 # mid-rule actions. We rely on %expect to check that there are
30 # indeed 65 SR conflicts.
32 # Bison was once wrong, due to an incorrect computation of nullable.
33 # It reported 485 SR conflicts!
38 %token FUNC_CALL NAME REGEXP
40 %token YNUMBER YSTRING
41 %token RELOP APPEND_OP
42 %token ASSIGNOP MATCHOP NEWLINE CONCAT_OP
43 %token LEX_BEGIN LEX_END LEX_IF LEX_ELSE LEX_RETURN LEX_DELETE
44 %token LEX_WHILE LEX_DO LEX_FOR LEX_BREAK LEX_CONTINUE
45 %token LEX_PRINT LEX_PRINTF LEX_NEXT LEX_EXIT LEX_FUNCTION
46 %token LEX_GETLINE LEX_NEXTFILE
48 %token LEX_AND LEX_OR INCREMENT DECREMENT
49 %token LEX_BUILTIN LEX_LENGTH
51 /* Lowest to highest */
58 %left FUNC_CALL LEX_BUILTIN LEX_LENGTH
61 %nonassoc RELOP '<' '>' '|' APPEND_OP TWOWAYIO
68 %left INCREMENT DECREMENT
74 : opt_nls program opt_nls
88 | LEX_BEGIN statement_term
89 | LEX_END statement_term
92 | pattern statement_term
93 | function_prologue function_body
108 : LEX_FUNCTION {} func_name '(' opt_param_list r_paren opt_nls
112 : l_brace statements r_brace opt_semi opt_nls
113 | l_brace r_brace opt_semi opt_nls
124 * In this rule, want_regexp tells yylex that the next thing
125 * is a regexp so it should read up to the closing slash.
131 : l_brace statements r_brace opt_semi opt_nls
132 | l_brace r_brace opt_semi opt_nls
137 | statements statement
150 | l_brace statements r_brace
152 | LEX_WHILE '(' exp r_paren opt_nls statement
153 | LEX_DO opt_nls statement LEX_WHILE '(' exp r_paren opt_nls
154 | LEX_FOR '(' NAME LEX_IN NAME r_paren opt_nls statement
155 | LEX_FOR '(' opt_exp semi opt_nls exp semi opt_nls opt_exp r_paren opt_nls statement
156 | LEX_FOR '(' opt_exp semi opt_nls semi opt_nls opt_exp r_paren opt_nls statement
157 | LEX_BREAK statement_term
158 | LEX_CONTINUE statement_term
159 | print '(' expression_list r_paren output_redir statement_term
160 | print opt_rexpression_list output_redir statement_term
161 | LEX_NEXT statement_term
162 | LEX_NEXTFILE statement_term
163 | LEX_EXIT opt_exp statement_term
164 | LEX_RETURN {} opt_exp statement_term
165 | LEX_DELETE NAME '[' expression_list ']' statement_term
166 | LEX_DELETE NAME statement_term
176 : LEX_IF '(' exp r_paren opt_nls statement
177 | LEX_IF '(' exp r_paren opt_nls statement
178 LEX_ELSE opt_nls statement
211 | param_list comma NAME
214 | param_list comma error
217 /* optional expression, as in for loop */
230 | rexpression_list comma rexp
232 | rexpression_list error
233 | rexpression_list error rexp
234 | rexpression_list comma error
244 | expression_list comma exp
246 | expression_list error
247 | expression_list error exp
248 | expression_list comma error
251 /* Expressions, not including the comma operator. */
252 exp : variable ASSIGNOP {} exp
253 | '(' expression_list r_paren LEX_IN NAME
254 | exp '|' LEX_GETLINE opt_variable
255 | exp TWOWAYIO LEX_GETLINE opt_variable
256 | LEX_GETLINE opt_variable input_redir
261 | '!' regexp %prec UNARY
266 | exp '?' exp ':' exp
268 | exp simp_exp %prec CONCAT_OP
272 : variable ASSIGNOP {} rexp
275 | LEX_GETLINE opt_variable input_redir
277 | '!' regexp %prec UNARY
281 | rexp '?' rexp ':' rexp
283 | rexp simp_exp %prec CONCAT_OP
288 /* Binary operators in order of decreasing precedence. */
289 | simp_exp '^' simp_exp
290 | simp_exp '*' simp_exp
291 | simp_exp '/' simp_exp
292 | simp_exp '%' simp_exp
293 | simp_exp '+' simp_exp
294 | simp_exp '-' simp_exp
300 : '!' simp_exp %prec UNARY
303 '(' opt_expression_list r_paren
304 | LEX_LENGTH '(' opt_expression_list r_paren
306 | FUNC_CALL '(' opt_expression_list r_paren
312 | '-' simp_exp %prec UNARY
313 | '+' simp_exp %prec UNARY
323 | NAME '[' expression_list ']'
324 | '$' non_post_simp_exp
354 # Pass plenty of options, to exercise plenty of code, even if we
355 # don't actually check the output. But SEGV is watching us, and
356 # so might do dmalloc.
357 AT_CHECK([[bison --verbose --defines input.y]])
362 ## ----------------- ##
363 ## GNU Cim Grammar. ##
364 ## ----------------- ##
366 AT_SETUP([GNU Cim Grammar])
368 # GNU Cim, the GNU Simula 87 Compiler.
370 # Bison was once wrong, due to an incorrect computation of the RR conflicts.
371 # It reported 80 SR && 99 RR conflicts instead of 78/10!!!
385 HACTIVATE HAFTER /*HAND*/ HARRAY HAT
386 HBEFORE HBEGIN HBOOLEAN
387 HCHARACTER HCLASS /*HCOMMENT*/ HCONC
389 HELSE HEND HEQ /*HEQV*/ HEXTERNAL
393 HIF /*HIMP*/ HIN HINNER HINSPECT HINTEGER HIS
395 HNAME HNE HNEW HNONE /*HNOT*/ HNOTEXT
397 HPRIOR HPROCEDURE HPROTECTED
399 HREACTIVATE HREAL HREF
401 HTEXT HTHEN HTHIS HTO
406 HASSIGNVALUE HASSIGNREF
407 /*HDOT*/ HPAREXPSEPARATOR HLABELSEPARATOR HSTATEMENTSEPARATOR
410 HADD HSUB HMUL HDIV HINTDIV HEXP
413 %token <ident> HIDENTIFIER
414 %token <ival> HBOOLEANKONST HINTEGERKONST HCHARACTERKONST
415 %token <rval> HREALKONST
416 %token <tval> HTEXTKONST
418 %type <tval> EXT_IDENT
419 %type <stat_decl> DECLSTATEMENT MODULSTATEMENT MBEE_DECLSTMS MBEE_DECLSTMSU
420 %type <stat_decl> MODULS
421 %type <ident> EXPRESSION_SIMP MBEE_ARG_R_PT
422 %type <arrdim> BAUND_PAIR_LIST
424 %right <token> HASSIGN
434 %left <token> HVALRELOPERATOR HREFRELOPERATOR HOBJRELOPERATOR
438 %left <token> HTERMOPERATOR
440 %left <token> HFACTOROPERATOR
441 %left HPRIMARYOPERATOR
449 /* GRAMATIKK FOR PROGRAM MODULES */
450 MAIN_MODULE : { categ=CLOCAL; mout(MBLOCK);
451 beginBlock(KBLOKK);separat_comp=FALSE;}
452 MODULS { endBlock(NULL,CCNO); mout(MENDBLOCK);}
453 | error HSTATEMENTSEPARATOR MBEE_DECLSTMS
455 EXT_DECLARATION : HEXTERNAL
468 if($2==Ckind)categ=CCPROC;else
470 ysensitive=sensitive;
472 HIDENTIFIER { $<ident>$=$5;
473 sensitive=ysensitive;}
483 EXTERNAL_KIND_ITEM: EXT_IDENT
485 { if($2!=HIS)yerror (2);}
488 { regDecl($6, type, KPROC, CCPROC);
492 endBlock($1==NULL?$<ident>0:tag($1),CCCPROC);}
495 { if($1!=NULL)yerror (3);
496 regDecl($0, type, kind, categ);}
498 { endBlock(NULL,CCNO);}
500 MBEE_REST_EXT_LIST: /* EMPTY
501 | HPAREXPSEPARATOR EXT_KIND_LIST
503 EXT_KIND_LIST : EXT_KIND_ITEM
504 | EXT_KIND_LIST HPAREXPSEPARATOR EXT_KIND_ITEM
506 EXT_KIND_ITEM : HIDENTIFIER
508 { if($2!=NULL)yerror (3);
509 regDecl($1, type, kind, categ);}*/
511 EMPTY_BLOCK : /*EMPT*/
515 | EXT_LIST HPAREXPSEPARATOR EXT_ITEM
517 EXT_ITEM : HIDENTIFIER
519 { lesinn_external_spec($1,$2, kind);}
521 EXT_IDENT : /* EMPTY */ { $$=NULL;}
522 | HVALRELOPERATOR { if($1!=HEQ)yerror (9);
524 HTEXTKONST { $$=$3;external=FALSE;}
526 /* GRAMATIKK FOR TYPER */
527 NO_TYPE : /*EMPT*/ { type=TNOTY;}
537 | HTEXT { type=TTEXT;}
538 | HBOOLEAN { type=TBOOL;}
539 | HCHARACTER { type=TCHAR;}
540 | HSHORT HINTEGER { type=TSHORT;}
541 | HINTEGER { type=TINTG;}
542 | HREAL { type=TREAL;}
543 | HLONG HREAL { type=TLONG;}
546 /* GRAMATIKK FOR DEL AV SETNINGER */
547 MBEE_ELSE_PART : /*EMPT*/
554 BLOCK { MBEEENDBLOCK();}
555 MBEE_ELSE_PART { mout(MENDIF);}*/
556 | HELSE { OBSBLOCK(); mout(MELSE);}
557 BLOCK { MBEEENDBLOCK();}
559 FOR_LIST : FOR_LIST_ELEMENT { mout(MENDSEP);
563 FOR_LIST { mout(MLISTSEP);}
565 FOR_LIST_ELEMENT: EXPRESSION
568 MBEE_F_L_EL_R_PT: /*EMPT*/
570 EXPRESSION { mout(MFORWHILE);}
574 EXPRESSION { mout(MUNTIL);
581 CONN_STATE_R_PT : WHEN_CLAUSE_LIST
582 | HDO { beginBlock(KCON); mout(MDO);
584 BLOCK { endBlock(NULL,CCNO);
585 MBEEENDBLOCK(); mout(MENDDO);}
587 WHEN_CLAUSE_LIST: HWHEN
589 HDO { beginBlock(KCON); mout(MIDENTIFIER);
590 OBSBLOCK(); moutId($2);
592 BLOCK { endBlock(NULL,CCNO);
593 MBEEENDBLOCK(); mout(MENDWHEN);}
597 HDO { beginBlock(KCON); mout(MIDENTIFIER);
598 OBSBLOCK(); moutId($3);
600 BLOCK { endBlock(NULL,CCNO);
601 MBEEENDBLOCK(); mout(MENDWHEN);}
603 MBEE_OTWI_CLAUS : /*EMPT*/
604 | HOTHERWISE {OBSBLOCK(); mout(MOTHERWISE);}
606 BLOCK {MBEEENDBLOCK();mout(MENDOTHERWISE);}
608 ACTIVATOR : HACTIVATE { mout(MBOOLEANKONST);
610 | HREACTIVATE { mout(MBOOLEANKONST);
613 SCHEDULE : /*EMPT*/ { mout(MCHARACTERKONST);
620 | ATDELAY EXPRESSION { mout(MNONE);}
622 | BEFOREAFTER { mout(MINTEGERKONST);
624 EXPRESSION { mout(MBOOLEANKONST);
627 ATDELAY : HAT { mout(MCHARACTERKONST);
629 | HDELAY { mout(MCHARACTERKONST);
632 BEFOREAFTER : HBEFORE { mout(MCHARACTERKONST);
634 | HAFTER { mout(MCHARACTERKONST);
637 PRIOR : /*EMPT*/ { mout(MBOOLEANKONST);
639 | HPRIOR { mout(MBOOLEANKONST);
642 /* GRAMATIKK FOR SETNINGER OG DEKLARASJONER */
643 MODULSTATEMENT : HWHILE
645 HDO { STOPOBSBLOCK(); mout(MWHILE);
647 BLOCK { MBEEENDBLOCK(); mout(MENDWHILE);
651 HTHEN { STOPOBSBLOCK(); mout(MIF);
653 BLOCK { MBEEENDBLOCK();}
654 MBEE_ELSE_PART { mout(MENDIF);
658 HASSIGN { STOPOBSBLOCK(); mout(MIDENTIFIER);
661 HDO { beginBlock(KFOR);
662 if($3==HASSIGNVALUE) mout(MFOR);
664 OBSBLOCK(); mout(MFORDO);}
665 BLOCK { MBEEENDBLOCK();
666 endBlock(NULL,CCNO); mout(MENDFOR);
669 EXPRESSION { mout(MGOTO);
670 STOPOBSBLOCK(); $$=STATEMENT;}
672 EXPRESSION { mout(MINSPECT);
676 { endBlock(NULL,CCNO);}
677 MBEE_OTWI_CLAUS { mout(MENDINSPECT);
679 | HINNER { STOPOBSBLOCK(); mout(MINNER);
680 regInner(); $$=STATEMENT;}
684 regDecl($1, TLABEL, KSIMPLE, categ); mout(MLABEL);
687 DECLSTATEMENT { if($4<=DECLARATION)
699 HEND { endBlock(NULL,CCNO); mout(MENDPRBLOCK);
701 | EXPRESSION_SIMP HBEGIN error HSTATEMENTSEPARATOR
702 MBEE_DECLSTMS HEND { $$=STATEMENT;
703 endBlock(NULL,CCNO); mout(MENDPRBLOCK);}
704 | EXPRESSION_SIMP HBEGIN error HEND
706 endBlock(NULL,CCNO); mout(MENDPRBLOCK);}
709 { STOPOBSBLOCK(); $$=STATEMENT;
711 | ACTIVATOR EXPRESSION SCHEDULE
727 HEND { MBEEENDBLOCK(); $$=STATEMENT;}
728 | MBEE_TYPE HPROCEDURE
730 { MBEENEWBLOCK(); mout(MPROCEDURE);
731 regDecl($3, type, KPROC, categ);
733 HEADING BLOCK { endBlock(NULL,CCNO); $$=DECLARATION;
734 mout(MENDPROCEDURE);}
743 regDecl($6, TNOTY, KCLASS, categ);
746 BLOCK { endBlock(NULL,CCNO); $$=DECLARATION;
752 MBEENEWBLOCK(); mout(MCLASS);
753 regDecl($3, TNOTY, KCLASS, categ);
756 BLOCK { endBlock(NULL,CCNO); $$=DECLARATION;
758 | EXT_DECLARATION { $$=EXTDECLARATION;}
759 | /*EMPT*/{ STOPOBSBLOCK(); $$=EMPTYSTATEMENT;}
761 IMPORT_SPEC_MODULE: { MBEENEWBLOCK();
763 if($<ident>0==simsetident &&
764 findDecl(simsetident,cblock,FALSE)==NULL)
765 lesinn_external_spec(simsetident,
766 SIMSETATRFILE, kind);
767 if($<ident>0==simulationident && findDecl(
768 simulationident,cblock,FALSE)==NULL)
769 lesinn_external_spec(simulationident,
770 SIMULATIONATRFILE, kind);
771 if(($<ident>0==fileident && findDecl(
772 fileident,cblock,FALSE)==NULL) ||
773 ($<ident>0==outfileident && findDecl(
774 outfileident,cblock,FALSE)==NULL) ||
775 ($<ident>0==infileident && findDecl(
776 infileident,cblock,FALSE)==NULL) ||
777 ($<ident>0==directfileident && findDecl(
778 directfileident,cblock,FALSE)==NULL) ||
779 ($<ident>0==printfileident && findDecl(
780 printfileident,cblock,FALSE)==NULL) ||
781 ($<ident>0==bytefileident && findDecl(
782 bytefileident,cblock,FALSE)==NULL) ||
783 ($<ident>0==inbytefileident && findDecl(
784 inbytefileident,cblock,FALSE)==NULL) ||
785 ($<ident>0==outbytefileident && findDecl(
786 outbytefileident,cblock,FALSE)==NULL) ||
787 ($<ident>0==directbytefileident && findDecl(
788 directbytefileident,cblock,FALSE)==NULL))
789 lesinn_external_spec(fileident,
792 DECLSTATEMENT : MODULSTATEMENT
799 regDecl($2, type, KSIMPLE, categ);
801 IDENTIFIER_LISTC { $$=DECLARATION;}
806 regDecl($2, type, KSIMPLE, categ);
807 categ=CLOCAL; $$=DECLARATION;}
809 HARRAY { MBEENEWBLOCK();
811 ARR_SEGMENT_LIST { $$=DECLARATION;}
814 HASSIGN { MBEENEWBLOCK(); mout(MIDENTIFIER);
816 regDecl($2, TLABEL, KARRAY, categ);}
817 SWITCH_LIST { $$=DECLARATION;
821 BLOCK : DECLSTATEMENT { if($1<=DECLARATION)yerror (29);}
822 | HBEGIN MBEE_DECLSTMS HEND
823 | HBEGIN error HSTATEMENTSEPARATOR MBEE_DECLSTMS HEND
826 MBEE_DECLSTMS : MBEE_DECLSTMSU { if($1<=DECLARATION)yerror (28);
829 MBEE_DECLSTMSU : DECLSTATEMENT { $$=$1;}
832 DECLSTATEMENT { if($1>=STATEMENT && $3<=DECLARATION)
836 MODULS : MODULSTATEMENT { if($1==DECLARATION)
837 {separat_comp=TRUE;gettimestamp();}
839 | MODULS HSTATEMENTSEPARATOR MODULSTATEMENT
840 { if($1>=STATEMENT && $3<=DECLARATION)
843 && $3!=EMPTYSTATEMENT)yerror (25);
844 if(separat_comp && $3==STATEMENT)
846 if($3==DECLARATION && !separat_comp)
847 {separat_comp=TRUE;gettimestamp();}
850 /* GRAMATIKK FOR DEL AV DEKLARASJONER */
851 ARR_SEGMENT_LIST: ARR_SEGMENT
856 ARR_SEGMENT : ARRAY_SEGMENT
858 BAUND_PAIR_LIST HENDPAR { mout(MARRAY);
862 ARRAY_SEGMENT : ARRAY_SEGMENT_EL { mout(MENDSEP);
867 ARRAY_SEGMENT { mout(MARRAYSEP);}
869 ARRAY_SEGMENT_EL: HIDENTIFIER { mout(MIDENTIFIER);
871 regDecl($1, type, kind, categ);
873 lastArray=cblock->lastparloc;}
875 BAUND_PAIR_LIST : BAUND_PAIR { mout(MENDSEP);
880 BAUND_PAIR_LIST { mout(MBOUNDSEP);
883 BAUND_PAIR : EXPRESSION
885 EXPRESSION { mout(MBOUNDPARSEP);}
887 SWITCH_LIST : EXPRESSION { mout(MENDSEP);
891 SWITCH_LIST { mout(MSWITCHSEP);}
893 HEADING : MBEE_FMAL_PAR_P HSTATEMENTSEPARATOR { kind=KNOKD;}
894 MBEE_MODE_PART { categ=CSPEC;}
895 MBEE_SPEC_PART { kind=KNOKD;}
896 MBEE_PROT_PART { categ=CVIRT;}
900 MBEE_FMAL_PAR_P : /*EMPT*/
903 FMAL_PAR_PART : HBEGPAR NO_TYPE
906 MBEE_LISTV : /*EMPT*/
909 LISTV : HIDENTIFIER { regDecl($1, type, KNOKD, CDEFLT);}
910 | FPP_CATEG HDOTDOTDOT { regDecl(varargsid, TVARARGS, KNOKD, categ);}
911 | HIDENTIFIER { regDecl($1, type, KNOKD, CDEFLT);}
912 HPAREXPSEPARATOR LISTV {}
915 HPAREXPSEPARATOR LISTV
917 FPP_HEADING : HBEGPAR NO_TYPE
918 FPP_MBEE_LISTV HENDPAR
920 FPP_MBEE_LISTV : /*EMPT*/
923 FPP_LISTV : FPP_CATEG HDOTDOTDOT { regDecl(varargsid, TVARARGS, KNOKD, categ);}
926 HPAREXPSEPARATOR LISTV
928 FPP_SPEC : FPP_CATEG SPECIFIER HIDENTIFIER
929 { regDecl($3, type, kind, categ);}
930 | FPP_CATEG FPP_PROC_DECL_IN_SPEC
932 FPP_CATEG : HNAME HLABELSEPARATOR
934 | HVALUE HLABELSEPARATOR
936 | HVAR HLABELSEPARATOR
938 | /*EMPT*/ { categ=CDEFLT;}
940 FPP_PROC_DECL_IN_SPEC: MBEE_TYPE HPROCEDURE
943 regDecl($3, type, KPROC, categ);
946 { categ=$<ival>4; /* M} settes tilbake*/}
947 { endBlock(NULL,CCNO);}
949 IDENTIFIER_LISTV: HIDENTIFIER { regDecl($1, type, kind, categ);}
950 | HDOTDOTDOT { regDecl(varargsid, TVARARGS, kind, categ);}
951 | HIDENTIFIER { regDecl($1, type, kind, categ);}
952 HPAREXPSEPARATOR IDENTIFIER_LISTV {}
954 MBEE_MODE_PART : /*EMPT*/
957 MODE_PART : NAME_PART
960 | NAME_PART VALUE_PART
961 | VALUE_PART NAME_PART
964 | VALUE_PART VAR_PART
965 | VAR_PART VALUE_PART
966 | VAR_PART NAME_PART VALUE_PART
967 | NAME_PART VAR_PART VALUE_PART
968 | NAME_PART VALUE_PART VAR_PART
969 | VAR_PART VALUE_PART NAME_PART
970 | VALUE_PART VAR_PART NAME_PART
971 | VALUE_PART NAME_PART VAR_PART
973 NAME_PART : HNAME { categ=CNAME;}
977 VAR_PART : HVAR { categ=CVAR;}
981 VALUE_PART : HVALUE { categ=CVALUE;}
982 IDENTIFIER_LISTV HSTATEMENTSEPARATOR
984 MBEE_SPEC_PART : /*EMPT*/
990 ONE_SPEC : SPECIFIER IDENTIFIER_LIST HSTATEMENTSEPARATOR
991 | NO_TYPE HPROCEDURE HIDENTIFIER HOBJRELOPERATOR
992 { if($4!=HIS) yerror (8);}
993 PROC_DECL_IN_SPEC HSTATEMENTSEPARATOR
994 | FPP_PROC_DECL_IN_SPEC HSTATEMENTSEPARATOR
995 | MBEE_TYPE HPROCEDURE HIDENTIFIER HSTATEMENTSEPARATOR
997 | MBEE_TYPE HPROCEDURE HIDENTIFIER HPAREXPSEPARATOR
998 IDENTIFIER_LIST HSTATEMENTSEPARATOR
1001 SPECIFIER : TYPE { kind=KSIMPLE;}
1003 HARRAY { kind=KARRAY;}
1004 | HLABEL { type=TLABEL;
1006 | HSWITCH { type=TLABEL;
1009 PROC_DECL_IN_SPEC: MBEE_TYPE HPROCEDURE
1012 regDecl($3, type, KPROC, categ);
1015 { categ=$<ival>4; /* M} settes tilbake*/}
1017 { endBlock(NULL,CCNO);}
1019 MBEE_BEGIN_END : /* EMPTY */
1022 MBEE_PROT_PART : /*EMPT*/
1025 PROTECTION_PART : PROT_SPECIFIER IDENTIFIER_LIST
1027 | PROTECTION_PART PROT_SPECIFIER
1028 IDENTIFIER_LIST HSTATEMENTSEPARATOR
1030 PROT_SPECIFIER : HHIDDEN { categ=CHIDEN;}
1031 | HPROTECTED { categ=CPROT;}
1033 HPROTECTED { categ=CHIPRO;}
1035 HHIDDEN { categ=CHIPRO;}
1037 MBEE_VIRT_PART : /*EMPT*/
1040 VIRTUAL_PART : HVIRTUAL
1044 IDENTIFIER_LIST : HIDENTIFIER { regDecl($1, type, kind, categ);}
1045 | IDENTIFIER_LIST HPAREXPSEPARATOR
1046 HIDENTIFIER { regDecl($3, type, kind, categ);}
1048 IDENTIFIER_LISTC: HIDENTIFIER
1049 MBEE_CONSTANT { regDecl($1, type, kind, categ);
1051 | IDENTIFIER_LISTC HPAREXPSEPARATOR
1053 MBEE_CONSTANT { regDecl($3, type, kind, categ);
1056 MBEE_CONSTANT : /* EMPTY */
1059 if($1!=HEQ) yerror (8);
1060 if(type==TREF)yerror (7);
1064 EXPRESSION { mout(MASSIGN);
1068 /* GRAMATIKK FOR UTTRYKK */
1069 EXPRESSION : EXPRESSION_SIMP {}
1075 EXPRESSION { mout(MELSEE);
1078 EXPRESSION_SIMP : EXPRESSION_SIMP
1080 EXPRESSION { if($2==HASSIGNREF)mout(MASSIGNR);
1081 else mout(MASSIGN);$$=NULL;}
1086 EXPRESSION_SIMP { mout(MCONC);$$=NULL;}
1087 | EXPRESSION_SIMP HOR
1090 %prec HORELSE { mout(MORELSEE);$$=NULL;}
1091 | EXPRESSION_SIMP HAND
1094 %prec HANDTHEN { mout(MANDTHENE);$$=NULL;}
1096 HEQV EXPRESSION_SIMP { mout(MEQV);$$=NULL;}
1098 HIMP EXPRESSION_SIMP { mout(MIMP);$$=NULL;}
1100 HOR EXPRESSION_SIMP { mout(MOR);$$=NULL;}
1102 HAND EXPRESSION_SIMP { mout(MAND);$$=NULL;}
1103 | HNOT EXPRESSION_SIMP { mout(MNOT);$$=NULL;}
1108 { case HEQ: mout(MEQ);break;
1109 case HNE: mout(MNE);break;
1110 case HLT: mout(MLT);break;
1111 case HLE: mout(MLE);break;
1112 case HGT: mout(MGT);break;
1113 case HGE: mout(MGE);break;
1118 { if($2==HNER) mout(MNER);
1119 else mout(MEQR);$$=NULL;}
1123 { if($2==HIS) mout(MIS);
1124 else mout(MINS);$$=NULL;}
1126 EXPRESSION_SIMP %prec UNEAR
1127 { if($1==HADD) mout(MUADD);
1128 else mout(MUSUB);$$=NULL;}
1132 { if($2==HADD) mout(MADD);
1133 else mout(MSUB);$$=NULL;}
1137 { if($2==HMUL) mout(MMUL); else
1138 if($2==HDIV) mout(MDIV);
1139 else mout(MINTDIV);$$=NULL;}
1142 EXPRESSION_SIMP { mout(MPRIMARY);$$=NULL;}
1144 EXPRESSION HENDPAR { mout(MNOOP);$$=NULL;}
1145 | HTEXTKONST { mout(MTEXTKONST);
1146 moutTval($1);$$=NULL;}
1147 | HCHARACTERKONST { mout(MCHARACTERKONST);
1148 moutIval($1);$$=NULL;}
1149 | HREALKONST { mout(MREALKONST);
1150 moutRval($1);$$=NULL;}
1151 | HINTEGERKONST { mout(MINTEGERKONST);
1152 moutIval($1);$$=NULL;}
1153 | HBOOLEANKONST { mout(MBOOLEANKONST);
1154 moutIval($1);$$=NULL;}
1155 | HNONE { mout(MNONE);$$=NULL;}
1159 | HTHIS HIDENTIFIER { mout(MTHIS);
1160 moutId($2);$$=NULL;}
1163 ARG_R_PT { mout(MNEWARG);
1164 moutId($2);$$=NULL;}
1167 EXPRESSION_SIMP { mout(MDOT);$$=NULL;}
1169 HQUA HIDENTIFIER { mout(MQUA);
1170 moutId($3);$$=NULL;}
1172 ARG_R_PT : /*EMPTY*/ { mout(MENDSEP);}
1174 ARGUMENT_LIST HENDPAR
1176 MBEE_ARG_R_PT : /*EMPTY*/ { mout(MIDENTIFIER);
1180 ARGUMENT_LIST HENDPAR { mout(MARGUMENT);
1183 ARGUMENT_LIST : EXPRESSION { mout(MENDSEP);
1184 mout(MARGUMENTSEP);}
1187 ARGUMENT_LIST { mout(MARGUMENTSEP);}
1192 # Pass plenty of options, to exercise plenty of code, even if we
1193 # don't actually check the output. But SEGV is watching us, and
1194 # so might do dmalloc.
1195 AT_CHECK([[bison --verbose --defines input.y]], 0, [],
1196 [[input.y: conflicts: 78 shift/reduce, 10 reduce/reduce
1199 AT_CHECK([[grep '^State.*conflicts:' input.output]], 0,
1200 [[State 64 conflicts: 14 shift/reduce
1201 State 164 conflicts: 1 shift/reduce
1202 State 201 conflicts: 33 shift/reduce, 4 reduce/reduce
1203 State 206 conflicts: 1 shift/reduce
1204 State 240 conflicts: 1 shift/reduce
1205 State 335 conflicts: 9 shift/reduce, 2 reduce/reduce
1206 State 356 conflicts: 1 shift/reduce
1207 State 360 conflicts: 9 shift/reduce, 2 reduce/reduce
1208 State 427 conflicts: 9 shift/reduce, 2 reduce/reduce
1214 ## ----------------- ##
1215 ## GNU pic Grammar. ##
1216 ## ----------------- ##
1218 AT_SETUP([GNU pic Grammar])
1220 # GNU pic, part of groff.
1222 # Bison once reported shift/reduce conflicts that it shouldn't have.
1224 AT_DATA([[input.y]],
1229 struct { double x, y; } pair;
1230 struct { double x; char *body; } if_data;
1231 struct { char *str; const char *filename; int lineno; } lstr;
1232 struct { double *v; int nv; int maxv; } dv;
1233 struct { double val; int is_multiplicative; } by;
1239 saved_state *pstate;
1240 graphics_state state;
1245 %token <str> VARIABLE
1248 %token <lstr> COMMAND_LINE
1249 %token <str> DELIMITED
1252 %token LEFT_ARROW_HEAD
1253 %token RIGHT_ARROW_HEAD
1254 %token DOUBLE_ARROW_HEAD
1364 /* this ensures that plot 17 "%g" parses as (plot 17 "%g") */
1368 /* give text adjustments higher precedence than TEXT, so that
1369 box "foo" above ljust == box ("foo" above ljust)
1372 %left LJUST RJUST ABOVE BELOW
1375 /* Give attributes that take an optional expression a higher
1376 precedence than left and right, so that eg `line chop left'
1378 %left CHOP SOLID DASHED DOTTED UP DOWN FILL COLORED OUTLINED
1381 %left VARIABLE NUMBER '(' SIN COS ATAN2 LOG EXP SQRT K_MAX K_MIN INT RAND SRAND LAST
1382 %left ORDINAL HERE '`'
1384 %left BOX CIRCLE ELLIPSE ARC LINE ARROW SPLINE '[' /* ] */
1386 /* these need to be lower than '-' */
1387 %left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS
1389 /* these must have higher precedence than CHOP so that `label %prec CHOP'
1391 %left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C
1392 %left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER
1393 %left UPPER LOWER NORTH SOUTH EAST WEST CENTER START END
1398 %left EQUALEQUAL NOTEQUAL
1399 %left '<' '>' LESSEQUAL GREATEREQUAL
1409 %type <x> expr any_expr text_expr
1410 %type <by> optional_by
1411 %type <pair> expr_pair position_not_place
1412 %type <if_data> simple_if
1413 %type <obj> nth_primitive
1415 %type <pth> path label_path relative_path
1416 %type <pl> place label element element_list middle_element_list
1417 %type <spec> object_spec
1418 %type <pair> position
1419 %type <obtype> object_type
1420 %type <n> optional_ordinal_last ordinal
1422 %type <dv> sprintf_args
1423 %type <lstr> text print_args print_arg
1432 print_picture(olist.head);
1438 optional_separator middle_element_list optional_separator
1442 middle_element_list:
1445 | middle_element_list separator element
1460 VARIABLE '=' any_expr
1462 define_variable($1, $3);
1465 | VARIABLE ':' '=' any_expr
1467 place *p = lookup_label($1);
1469 lex_error("variable `%1' not defined", $1);
1478 { current_direction = UP_DIRECTION; }
1480 { current_direction = DOWN_DIRECTION; }
1482 { current_direction = LEFT_DIRECTION; }
1484 { current_direction = RIGHT_DIRECTION; }
1487 olist.append(make_command_object($1.str, $1.filename,
1490 | COMMAND print_args
1492 olist.append(make_command_object($2.str, $2.filename,
1497 fprintf(stderr, "%s\n", $2.str);
1507 lex_error("unsafe to run command `%1'", $3);
1517 // do not delete the filename
1527 copy_file_thru($2.str, $5, $7);
1528 // do not delete the filename
1540 copy_rest_thru($4, $6);
1544 | FOR VARIABLE '=' expr TO expr optional_by DO
1551 do_for($2, $4, $6, $7.is_multiplicative, $7.val, $10);
1577 { define_variable("scale", 1.0); }
1586 | reset_variables VARIABLE
1591 | reset_variables ',' VARIABLE
1601 | print_args print_arg
1603 $$.str = new char[strlen($1.str) + strlen($2.str) + 1];
1604 strcpy($$.str, $1.str);
1605 strcat($$.str, $2.str);
1609 $$.filename = $1.filename;
1610 $$.lineno = $1.lineno;
1612 else if ($2.filename) {
1613 $$.filename = $2.filename;
1614 $$.lineno = $2.lineno;
1622 $$.str = new char[GDIGITS + 1];
1623 sprintf($$.str, "%g", $1);
1629 | position %prec ','
1631 $$.str = new char[GDIGITS + 2 + GDIGITS + 1];
1632 sprintf($$.str, "%g, %g", $1.x, $1.y);
1664 text EQUALEQUAL text
1666 $$ = strcmp($1.str, $3.str) == 0;
1670 | text NOTEQUAL text
1672 $$ = strcmp($1.str, $3.str) != 0;
1676 | text_expr ANDAND text_expr
1677 { $$ = ($1 != 0.0 && $3 != 0.0); }
1678 | text_expr ANDAND expr
1679 { $$ = ($1 != 0.0 && $3 != 0.0); }
1680 | expr ANDAND text_expr
1681 { $$ = ($1 != 0.0 && $3 != 0.0); }
1682 | text_expr OROR text_expr
1683 { $$ = ($1 != 0.0 || $3 != 0.0); }
1684 | text_expr OROR expr
1685 { $$ = ($1 != 0.0 || $3 != 0.0); }
1686 | expr OROR text_expr
1687 { $$ = ($1 != 0.0 || $3 != 0.0); }
1689 { $$ = ($2 == 0.0); }
1697 $$.is_multiplicative = 0;
1702 $$.is_multiplicative = 0;
1707 $$.is_multiplicative = 1;
1714 $$.obj = $1->make_object(¤t_position,
1715 ¤t_direction);
1720 olist.append($$.obj);
1722 $$.x = current_position.x;
1723 $$.y = current_position.y;
1726 | LABEL ':' optional_separator element
1729 define_label($1, & $$);
1732 | LABEL ':' optional_separator position_not_place
1737 define_label($1, & $$);
1740 | LABEL ':' optional_separator place
1743 define_label($1, & $$);
1748 $<state>$.x = current_position.x;
1749 $<state>$.y = current_position.y;
1750 $<state>$.dir = current_direction;
1754 current_position.x = $<state>2.x;
1755 current_position.y = $<state>2.y;
1756 current_direction = $<state>2.dir;
1765 $$.x = current_position.x;
1766 $$.y = current_position.y;
1779 { $$ = new object_spec(BOX_OBJECT); }
1781 { $$ = new object_spec(CIRCLE_OBJECT); }
1783 { $$ = new object_spec(ELLIPSE_OBJECT); }
1786 $$ = new object_spec(ARC_OBJECT);
1787 $$->dir = current_direction;
1791 $$ = new object_spec(LINE_OBJECT);
1792 lookup_variable("lineht", & $$->segment_height);
1793 lookup_variable("linewid", & $$->segment_width);
1794 $$->dir = current_direction;
1798 $$ = new object_spec(ARROW_OBJECT);
1799 lookup_variable("lineht", & $$->segment_height);
1800 lookup_variable("linewid", & $$->segment_width);
1801 $$->dir = current_direction;
1805 $$ = new object_spec(MOVE_OBJECT);
1806 lookup_variable("moveht", & $$->segment_height);
1807 lookup_variable("movewid", & $$->segment_width);
1808 $$->dir = current_direction;
1812 $$ = new object_spec(SPLINE_OBJECT);
1813 lookup_variable("lineht", & $$->segment_height);
1814 lookup_variable("linewid", & $$->segment_width);
1815 $$->dir = current_direction;
1819 $$ = new object_spec(TEXT_OBJECT);
1820 $$->text = new text_item($1.str, $1.filename, $1.lineno);
1824 $$ = new object_spec(TEXT_OBJECT);
1825 $$->text = new text_item(format_number(0, $2), 0, -1);
1829 $$ = new object_spec(TEXT_OBJECT);
1830 $$->text = new text_item(format_number($3.str, $2),
1831 $3.filename, $3.lineno);
1836 saved_state *p = new saved_state;
1838 p->x = current_position.x;
1839 p->y = current_position.y;
1840 p->dir = current_direction;
1841 p->tbl = current_table;
1842 p->prev = current_saved_state;
1843 current_position.x = 0.0;
1844 current_position.y = 0.0;
1845 current_table = new PTABLE(place);
1846 current_saved_state = p;
1847 olist.append(make_mark_object());
1851 current_position.x = $<pstate>2->x;
1852 current_position.y = $<pstate>2->y;
1853 current_direction = $<pstate>2->dir;
1854 $$ = new object_spec(BLOCK_OBJECT);
1855 olist.wrap_up_block(& $$->oblist);
1856 $$->tbl = current_table;
1857 current_table = $<pstate>2->tbl;
1858 current_saved_state = $<pstate>2->prev;
1861 | object_spec HEIGHT expr
1865 $$->flags |= HAS_HEIGHT;
1867 | object_spec RADIUS expr
1871 $$->flags |= HAS_RADIUS;
1873 | object_spec WIDTH expr
1877 $$->flags |= HAS_WIDTH;
1879 | object_spec DIAMETER expr
1882 $$->radius = $3/2.0;
1883 $$->flags |= HAS_RADIUS;
1885 | object_spec expr %prec HEIGHT
1888 $$->flags |= HAS_SEGMENT;
1891 $$->segment_pos.y += $2;
1893 case DOWN_DIRECTION:
1894 $$->segment_pos.y -= $2;
1896 case RIGHT_DIRECTION:
1897 $$->segment_pos.x += $2;
1899 case LEFT_DIRECTION:
1900 $$->segment_pos.x -= $2;
1907 $$->dir = UP_DIRECTION;
1908 $$->flags |= HAS_SEGMENT;
1909 $$->segment_pos.y += $$->segment_height;
1911 | object_spec UP expr
1914 $$->dir = UP_DIRECTION;
1915 $$->flags |= HAS_SEGMENT;
1916 $$->segment_pos.y += $3;
1921 $$->dir = DOWN_DIRECTION;
1922 $$->flags |= HAS_SEGMENT;
1923 $$->segment_pos.y -= $$->segment_height;
1925 | object_spec DOWN expr
1928 $$->dir = DOWN_DIRECTION;
1929 $$->flags |= HAS_SEGMENT;
1930 $$->segment_pos.y -= $3;
1935 $$->dir = RIGHT_DIRECTION;
1936 $$->flags |= HAS_SEGMENT;
1937 $$->segment_pos.x += $$->segment_width;
1939 | object_spec RIGHT expr
1942 $$->dir = RIGHT_DIRECTION;
1943 $$->flags |= HAS_SEGMENT;
1944 $$->segment_pos.x += $3;
1949 $$->dir = LEFT_DIRECTION;
1950 $$->flags |= HAS_SEGMENT;
1951 $$->segment_pos.x -= $$->segment_width;
1953 | object_spec LEFT expr
1956 $$->dir = LEFT_DIRECTION;
1957 $$->flags |= HAS_SEGMENT;
1958 $$->segment_pos.x -= $3;
1960 | object_spec FROM position
1963 $$->flags |= HAS_FROM;
1967 | object_spec TO position
1970 if ($$->flags & HAS_SEGMENT)
1971 $$->segment_list = new segment($$->segment_pos,
1972 $$->segment_is_absolute,
1974 $$->flags |= HAS_SEGMENT;
1975 $$->segment_pos.x = $3.x;
1976 $$->segment_pos.y = $3.y;
1977 $$->segment_is_absolute = 1;
1978 $$->flags |= HAS_TO;
1982 | object_spec AT position
1985 $$->flags |= HAS_AT;
1988 if ($$->type != ARC_OBJECT) {
1989 $$->flags |= HAS_FROM;
1994 | object_spec WITH path
1997 $$->flags |= HAS_WITH;
2000 | object_spec WITH position %prec ','
2003 $$->flags |= HAS_WITH;
2007 $$->with = new path(pos);
2009 | object_spec BY expr_pair
2012 $$->flags |= HAS_SEGMENT;
2013 $$->segment_pos.x += $3.x;
2014 $$->segment_pos.y += $3.y;
2019 if ($$->flags & HAS_SEGMENT) {
2020 $$->segment_list = new segment($$->segment_pos,
2021 $$->segment_is_absolute,
2023 $$->flags &= ~HAS_SEGMENT;
2024 $$->segment_pos.x = $$->segment_pos.y = 0.0;
2025 $$->segment_is_absolute = 0;
2032 | object_spec DOTTED
2035 $$->flags |= IS_DOTTED;
2036 lookup_variable("dashwid", & $$->dash_width);
2038 | object_spec DOTTED expr
2041 $$->flags |= IS_DOTTED;
2042 $$->dash_width = $3;
2044 | object_spec DASHED
2047 $$->flags |= IS_DASHED;
2048 lookup_variable("dashwid", & $$->dash_width);
2050 | object_spec DASHED expr
2053 $$->flags |= IS_DASHED;
2054 $$->dash_width = $3;
2059 $$->flags |= IS_DEFAULT_FILLED;
2061 | object_spec FILL expr
2064 $$->flags |= IS_FILLED;
2067 | object_spec SHADED text
2070 $$->flags |= (IS_SHADED | IS_FILLED);
2071 $$->shaded = new char[strlen($3.str)+1];
2072 strcpy($$->shaded, $3.str);
2074 | object_spec COLORED text
2077 $$->flags |= (IS_SHADED | IS_OUTLINED | IS_FILLED);
2078 $$->shaded = new char[strlen($3.str)+1];
2079 strcpy($$->shaded, $3.str);
2080 $$->outlined = new char[strlen($3.str)+1];
2081 strcpy($$->outlined, $3.str);
2083 | object_spec OUTLINED text
2086 $$->flags |= IS_OUTLINED;
2087 $$->outlined = new char[strlen($3.str)+1];
2088 strcpy($$->outlined, $3.str);
2093 // line chop chop means line chop 0 chop 0
2094 if ($$->flags & IS_DEFAULT_CHOPPED) {
2095 $$->flags |= IS_CHOPPED;
2096 $$->flags &= ~IS_DEFAULT_CHOPPED;
2097 $$->start_chop = $$->end_chop = 0.0;
2099 else if ($$->flags & IS_CHOPPED) {
2103 $$->flags |= IS_DEFAULT_CHOPPED;
2106 | object_spec CHOP expr
2109 if ($$->flags & IS_DEFAULT_CHOPPED) {
2110 $$->flags |= IS_CHOPPED;
2111 $$->flags &= ~IS_DEFAULT_CHOPPED;
2112 $$->start_chop = 0.0;
2115 else if ($$->flags & IS_CHOPPED) {
2119 $$->start_chop = $$->end_chop = $3;
2120 $$->flags |= IS_CHOPPED;
2126 $$->flags |= IS_SAME;
2128 | object_spec INVISIBLE
2131 $$->flags |= IS_INVISIBLE;
2133 | object_spec LEFT_ARROW_HEAD
2136 $$->flags |= HAS_LEFT_ARROW_HEAD;
2138 | object_spec RIGHT_ARROW_HEAD
2141 $$->flags |= HAS_RIGHT_ARROW_HEAD;
2143 | object_spec DOUBLE_ARROW_HEAD
2146 $$->flags |= (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD);
2151 $$->flags |= IS_CLOCKWISE;
2156 $$->flags &= ~IS_CLOCKWISE;
2158 | object_spec text %prec TEXT
2162 for (p = & $$->text; *p; p = &(*p)->next)
2164 *p = new text_item($2.str, $2.filename, $2.lineno);
2171 for (p = $$->text; p->next; p = p->next)
2173 p->adj.h = LEFT_ADJUST;
2181 for (p = $$->text; p->next; p = p->next)
2183 p->adj.h = RIGHT_ADJUST;
2191 for (p = $$->text; p->next; p = p->next)
2193 p->adj.v = ABOVE_ADJUST;
2201 for (p = $$->text; p->next; p = p->next)
2203 p->adj.v = BELOW_ADJUST;
2206 | object_spec THICKNESS expr
2209 $$->flags |= HAS_THICKNESS;
2212 | object_spec ALIGNED
2215 $$->flags |= IS_ALIGNED;
2222 | SPRINTF '(' TEXT sprintf_args ')'
2224 $$.filename = $3.filename;
2225 $$.lineno = $3.lineno;
2226 $$.str = do_sprintf($3.str, $4.v, $4.nv);
2239 | sprintf_args ',' expr
2242 if ($$.nv >= $$.maxv) {
2244 $$.v = new double[4];
2248 double *oldv = $$.v;
2250 $$.v = new double[$$.maxv];
2251 memcpy($$.v, oldv, $$.nv*sizeof(double));
2274 | position '+' expr_pair
2279 | position '-' expr_pair
2284 | '(' position ',' position ')'
2289 | expr between position AND position
2291 $$.x = (1.0 - $1)*$3.x + $1*$5.x;
2292 $$.y = (1.0 - $1)*$3.y + $1*$5.y;
2294 | expr '<' position ',' position '>'
2296 $$.x = (1.0 - $1)*$3.x + $1*$5.x;
2297 $$.y = (1.0 - $1)*$3.y + $1*$5.y;
2303 | OF THE WAY BETWEEN
2317 /* line at A left == line (at A) left */
2323 if (!pth.follow($1, & $$))
2329 if (!pth.follow($2, & $$))
2335 if (!pth.follow($3, & $$))
2340 $$.x = current_position.x;
2341 $$.y = current_position.y;
2349 place *p = lookup_label($1);
2351 lex_error("there is no place `%1'", $1);
2362 if (!pth.follow($1, & $$))
2372 // XXX Check for overflow (and non-integers?).
2377 optional_ordinal_last:
2389 for (p = olist.head; p != 0; p = p->next)
2390 if (p->type() == $2 && ++count == $1) {
2395 lex_error("there is no %1%2 %3", $1, ordinal_postfix($1),
2396 object_type_name($2));
2400 | optional_ordinal_last object_type
2404 for (p = olist.tail; p != 0; p = p->prev)
2405 if (p->type() == $2 && ++count == $1) {
2410 lex_error("there is no %1%2 last %3", $1,
2411 ordinal_postfix($1), object_type_name($2));
2419 { $$ = BOX_OBJECT; }
2421 { $$ = CIRCLE_OBJECT; }
2423 { $$ = ELLIPSE_OBJECT; }
2425 { $$ = ARC_OBJECT; }
2427 { $$ = LINE_OBJECT; }
2429 { $$ = ARROW_OBJECT; }
2431 { $$ = SPLINE_OBJECT; }
2433 { $$ = BLOCK_OBJECT; }
2435 { $$ = TEXT_OBJECT; }
2440 { $$ = new path($2); }
2441 | label_path '.' LABEL
2450 { $$ = new path($1); }
2451 /* give this a lower precedence than LEFT and RIGHT so that
2452 [A: box] with .A left == [A: box] with (.A left) */
2453 | label_path %prec TEXT
2465 | '(' relative_path ',' relative_path ')'
2470 /* The rest of these rules are a compatibility sop. */
2471 | ORDINAL LAST object_type relative_path
2473 lex_warning("`%1%2 last %3' in `with' argument ignored",
2474 $1, ordinal_postfix($1), object_type_name($3));
2477 | LAST object_type relative_path
2479 lex_warning("`last %1' in `with' argument ignored",
2480 object_type_name($2));
2483 | ORDINAL object_type relative_path
2485 lex_warning("`%1%2 %3' in `with' argument ignored",
2486 $1, ordinal_postfix($1), object_type_name($2));
2489 | LABEL relative_path
2491 lex_warning("initial `%1' in `with' argument ignored", $1);
2499 { $$ = &object::north; }
2501 { $$ = &object::east; }
2503 { $$ = &object::west; }
2505 { $$ = &object::south; }
2507 { $$ = &object::north_east; }
2509 { $$ = &object:: south_east; }
2511 { $$ = &object::north_west; }
2513 { $$ = &object::south_west; }
2515 { $$ = &object::center; }
2517 { $$ = &object::start; }
2519 { $$ = &object::end; }
2521 { $$ = &object::north; }
2523 { $$ = &object::south; }
2525 { $$ = &object::west; }
2527 { $$ = &object::east; }
2529 { $$ = &object::north_west; }
2531 { $$ = &object::south_west; }
2533 { $$ = &object::north_east; }
2535 { $$ = &object::south_east; }
2537 { $$ = &object::west; }
2539 { $$ = &object::east; }
2541 { $$ = &object::north_west; }
2543 { $$ = &object::south_west; }
2544 | UPPER RIGHT_CORNER
2545 { $$ = &object::north_east; }
2546 | LOWER RIGHT_CORNER
2547 { $$ = &object::south_east; }
2549 { $$ = &object::north; }
2551 { $$ = &object::south; }
2553 { $$ = &object::east; }
2555 { $$ = &object::west; }
2557 { $$ = &object::center; }
2559 { $$ = &object::start; }
2561 { $$ = &object::end; }
2567 if (!lookup_variable($1, & $$)) {
2568 lex_error("there is no variable `%1'", $1);
2578 $$ = $1.obj->origin().x;
2585 $$ = $1.obj->origin().y;
2592 $$ = $1.obj->height();
2599 $$ = $1.obj->width();
2606 $$ = $1.obj->radius();
2619 lex_error("division by zero");
2627 lex_error("modulus by zero");
2636 if (errno == EDOM) {
2637 lex_error("arguments to `^' operator out of domain");
2640 if (errno == ERANGE) {
2641 lex_error("result of `^' operator out of range");
2645 | '-' expr %prec '!'
2649 | SIN '(' any_expr ')'
2653 if (errno == ERANGE) {
2654 lex_error("sin result out of range");
2658 | COS '(' any_expr ')'
2662 if (errno == ERANGE) {
2663 lex_error("cos result out of range");
2667 | ATAN2 '(' any_expr ',' any_expr ')'
2671 if (errno == EDOM) {
2672 lex_error("atan2 argument out of domain");
2675 if (errno == ERANGE) {
2676 lex_error("atan2 result out of range");
2680 | LOG '(' any_expr ')'
2684 if (errno == ERANGE) {
2685 lex_error("log result out of range");
2689 | EXP '(' any_expr ')'
2693 if (errno == ERANGE) {
2694 lex_error("exp result out of range");
2698 | SQRT '(' any_expr ')'
2702 if (errno == EDOM) {
2703 lex_error("sqrt argument out of domain");
2707 | K_MAX '(' any_expr ',' any_expr ')'
2708 { $$ = $3 > $5 ? $3 : $5; }
2709 | K_MIN '(' any_expr ',' any_expr ')'
2710 { $$ = $3 < $5 ? $3 : $5; }
2711 | INT '(' any_expr ')'
2713 | RAND '(' any_expr ')'
2714 { $$ = 1.0 + floor(((rand()&0x7fff)/double(0x7fff))*$3); }
2717 /* return a random number in the range >=0, <1 */
2718 /* portable, but not very random */
2719 $$ = (rand() & 0x7fff) / double(0x8000);
2721 | SRAND '(' any_expr ')'
2724 srand((unsigned int)$3);
2728 | expr LESSEQUAL expr
2729 { $$ = ($1 <= $3); }
2732 | expr GREATEREQUAL expr
2733 { $$ = ($1 >= $3); }
2734 | expr EQUALEQUAL expr
2735 { $$ = ($1 == $3); }
2736 | expr NOTEQUAL expr
2737 { $$ = ($1 != $3); }
2739 { $$ = ($1 != 0.0 && $3 != 0.0); }
2741 { $$ = ($1 != 0.0 || $3 != 0.0); }
2743 { $$ = ($2 == 0.0); }
2748 # Pass plenty of options, to exercise plenty of code, even if we
2749 # don't actually check the output. But SEGV is watching us, and
2750 # so might do dmalloc.
2751 AT_CHECK([[bison --verbose --defines input.y]], 0, [], [])