4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1988 AT&T */
27 /* All Rights Reserved */
29 #pragma ident "%Z%%M% %I% %E% SMI"
35 #define IDENTIFIER 257
44 #define C_IDENTIFIER 265 /* name followed by colon */
51 #define LHS_TEXT_LEN 80 /* length of lhstext */
52 #define RHS_TEXT_LEN 640 /* length of rhstext */
53 /* communication variables between various I/O routines */
57 #define DEFAULT_PREFIX "y"
59 char *infile
; /* input file name */
60 static int numbval
; /* value of an input number */
61 static int toksize
= NAMESIZE
;
62 static wchar_t *tokname
; /* input token name */
63 char *parser
= PARSER
; /* location of common parser */
65 static void finact(void);
66 static wchar_t *cstash(wchar_t *);
67 static void defout(void);
68 static void cpyunion(void);
69 static void cpycode(void);
70 static void cpyact(int);
71 static void lhsfill(wchar_t *);
72 static void rhsfill(wchar_t *);
73 static void lrprnt(void);
74 static void beg_debug(void);
75 static void end_toks(void);
76 static void end_debug(void);
77 static void exp_tokname(void);
78 static void exp_prod(void);
79 static void exp_ntok(void);
80 static void exp_nonterm(void);
81 static int defin(int, wchar_t *);
82 static int gettok(void);
83 static int chfind(int, wchar_t *);
84 static int skipcom(void);
85 static int findchtok(int);
86 static void put_prefix_define(char *);
89 /* storage of names */
92 * initial block to place token and
93 * nonterminal names are stored
94 * points to initial block - more space
95 * is allocated as needed.
97 static wchar_t cnamesblk0
[CNAMSZ
];
98 static wchar_t *cnames
= cnamesblk0
;
100 /* place where next name is to be put in */
101 static wchar_t *cnamp
= cnamesblk0
;
103 /* number of defined symbols output */
104 static int ndefout
= 3;
106 /* storage of types */
107 static int defunion
= 0; /* union of types defined? */
108 static int ntypes
= 0; /* number of types defined */
109 static wchar_t *typeset
[NTYPES
]; /* pointers to type tags */
111 /* symbol tables for tokens and nonterminals */
120 int nnontersz
= NNONTERM
;
122 static int start
; /* start symbol */
124 /* assigned token type values */
125 static int extval
= 0;
127 /* input and output file descriptors */
129 FILE *finput
; /* yacc input file */
130 FILE *faction
; /* file for saving actions */
131 FILE *fdefine
; /* file for # defines */
132 FILE *ftable
; /* y.tab.c file */
133 FILE *ftemp
; /* tempfile to pass 2 */
134 FILE *fdebug
; /* where the strings for debugging are stored */
135 FILE *foutput
; /* y.output file */
139 static wchar_t *lhstext
;
140 static wchar_t *rhstext
;
142 /* storage for grammar rules */
144 int *mem0
; /* production storage */
147 extern int *optimmem
;
148 int new_memsize
= MEMSIZE
;
149 int nprod
= 1; /* number of productions */
156 /* flag for generating the # line's default is yes */
160 /* flag for whether to include runtime debugging */
161 static int gen_testing
= 0;
163 /* flag for version stamping--default turned off */
164 static char *v_stmp
= "n";
166 int nmbchars
= 0; /* number of mb literals in mbchars */
167 MBCLIT
*mbchars
= (MBCLIT
*) 0; /* array of mb literals */
168 int nmbcharsz
= 0; /* allocated space for mbchars */
174 { int ii
, i
, j
, lev
, t
, ty
;
175 /* ty is the sequencial number of token name in tokset */
180 unsigned int options
= 0;
181 char *file_prefix
= DEFAULT_PREFIX
;
182 char *sym_prefix
= "";
183 #define F_NAME_LENGTH 128
184 char fname
[F_NAME_LENGTH
+1];
190 tokname
= (wchar_t *)malloc(sizeof (wchar_t) * toksize
);
191 tokset
= (TOKSYMB
*)malloc(sizeof (TOKSYMB
) * ntoksz
);
192 toklev
= (int *)malloc(sizeof (int) * ntoksz
);
193 nontrst
= (NTSYMB
*)malloc(sizeof (NTSYMB
) * nnontersz
);
194 mem0
= (int *)malloc(sizeof (int) * new_memsize
);
195 prdptr
= (int **)malloc(sizeof (int *) * (nprodsz
+2));
196 levprd
= (int *)malloc(sizeof (int) * (nprodsz
+2));
197 had_act
= (wchar_t *)calloc((nprodsz
+ 2), sizeof (wchar_t));
198 lhstext
= (wchar_t *)calloc(1, sizeof (wchar_t) * LHS_TEXT_LEN
);
199 rhstext
= (wchar_t *)calloc(1, sizeof (wchar_t) * RHS_TEXT_LEN
);
200 aryfil(toklev
, ntoksz
, 0);
201 aryfil(levprd
, nprodsz
, 0);
202 for (ii
= 0; ii
< ntoksz
; ++ii
)
203 tokset
[ii
].value
= 0;
204 for (ii
= 0; ii
< nnontersz
; ++ii
)
205 nontrst
[ii
].tvalue
= 0;
206 aryfil(mem0
, new_memsize
, 0);
210 while ((c
= getopt(argc
, argv
, "vVdltp:Q:Y:P:b:")) != EOF
)
216 (void) fprintf(stderr
, "yacc: %s %s\n",
217 (const char *)SGU_PKG
,
218 (const char *)SGU_REL
);
222 if (*v_stmp
!= 'y' && *v_stmp
!= 'n')
224 * TRANSLATION_NOTE -- This is a message from yacc.
225 * This message is passed to error() function.
226 * Do not translate -Q and [y/n].
229 "yacc: -Q should be followed by [y/n]"));
235 gen_lines
= 0; /* don't gen #lines */
238 gen_testing
= 1; /* set YYDEBUG on */
241 cp
= (char *)malloc(strlen(optarg
)+
242 sizeof ("/yaccpar") + 1);
243 cp
= strcpy(cp
, optarg
);
244 parser
= strcat(cp
, "/yaccpar");
250 if (strcmp(optarg
, "yy") != 0)
256 file_prefix
= optarg
;
261 * TRANSLATION_NOTE -- This is a message from yacc.
262 * This message is passed to error() function.
263 * This is a usage message. The translate should be
264 * consistent with man page translation.
266 (void) fprintf(stderr
, gettext(
267 "Usage: yacc [-vVdltY] [-Q(y/n)] [-b file_prefix] [-p sym_prefix]"
268 " [-P parser] file\n"));
272 * Open y.output if -v is specified
274 if (options
& v_FLAG
) {
275 (void) strncpy(fname
,
277 F_NAME_LENGTH
-strlen(".output"));
278 (void) strcat(fname
, ".output");
279 foutput
= fopen(fname
, "w");
282 "cannot open y.output"));
286 * Open y.tab.h if -d is specified
288 if (options
& d_FLAG
) {
289 (void) strncpy(fname
,
291 F_NAME_LENGTH
-strlen(".tab.h"));
292 (void) strcat(fname
, ".tab.h");
293 fdefine
= fopen(fname
, "w");
296 "cannot open y.tab.h"));
299 fdebug
= fopen(DEBUGNAME
, "w");
302 * TRANSLATION_NOTE -- This is a message from yacc.
303 * This message is passed to error() function.
304 * Do not translate yacc.debug.
307 "cannot open yacc.debug"));
311 (void) strncpy(fname
,
313 F_NAME_LENGTH
-strlen(".tab.c"));
314 (void) strcat(fname
, ".tab.c");
315 ftable
= fopen(fname
, "w");
318 "cannot open %s"), fname
);
320 ftemp
= fopen(TEMPNAME
, "w");
321 faction
= fopen(ACTNAME
, "w");
322 if (ftemp
== NULL
|| faction
== NULL
)
324 * TRANSLATION_NOTE -- This is a message from yacc.
325 * This message is passed to error() function.
326 * The message means: "Could not open a temporary file."
329 "cannot open temp file"));
331 if ((finput
= fopen(infile
= argv
[optind
], "r")) == NULL
)
333 * TRANSLATION_NOTE -- This is a message from yacc.
334 * This message is passed to error() function.
337 "cannot open input file"));
341 (void) defin(0, L
"$end");
343 (void) defin(0, L
"error");
344 (void) defin(1, L
"$accept");
349 beg_debug(); /* initialize fdebug file */
352 * sorry -- no yacc parser here.....
353 * we must bootstrap somehow...
358 (void) fprintf(ftable
, "#ident\t\"yacc: %s %s\"\n",
359 (const char *)SGU_PKG
, (const char *)SGU_REL
);
360 for (; t
!= MARK
&& t
!= ENDFILE
; ) {
369 if ((t
= gettok()) != IDENTIFIER
) {
370 error("bad %%start construction");
372 start
= chfind(1, tokname
);
378 if ((t
= gettok()) != TYPENAME
)
380 * TRANSLATION_NOTE -- This is a message from yacc.
381 * This message is passed to error() function.
382 * Do not translate %%type.
385 "bad syntax in %%type"));
393 * The following lines are idented to left.
396 if ((t
= chfind(1, tokname
)) < NTBASE
) {
398 if (j
!= 0 && j
!= ty
) {
400 * TRANSLATION_NOTE -- This is a message from yacc.
401 * This message is passed to error() function.
404 "type redeclaration of token %ws"),
408 SETTYPE(toklev
[t
], ty
);
410 j
= nontrst
[t
-NTBASE
].tvalue
;
411 if (j
!= 0 && j
!= ty
) {
413 * TRANSLATION_NOTE -- This is a message from yacc.
414 * This message is passed to error() function.
415 * Check how nonterminal is translated in translated
416 * yacc man page or yacc user's document.
419 "type redeclaration of nonterminal %ws"),
420 nontrst
[t
-NTBASE
].name
);
423 nontrst
[t
-NTBASE
].tvalue
= ty
;
440 * TRANSLATION_NOTE -- This is a message from yacc.
441 * This message is passed to error() function.
444 "missing tokens or illegal tokens"));
450 /* copy the union declaration to the output */
464 /* nonzero means new prec. and assoc. */
468 /* get identifiers so defined */
471 if (t
== TYPENAME
) { /* there is a type defined */
488 j
= chfind(0, tokname
);
491 * TRANSLATION_NOTE -- This is a message from yacc.
492 * This message is passed to error() function.
495 "%ws is not a token."),
499 if (ASSOC(toklev
[j
]) & ~04)
501 * TRANSLATION_NOTE -- This is a message from yacc.
502 * This message is passed to error() function.
505 "redeclaration of precedence of %ws"),
507 SETASC(toklev
[j
], lev
);
508 SETPLEV(toklev
[j
], i
);
510 if (ASSOC(toklev
[j
]))
511 (void) warning(1, gettext(
512 "redeclaration of precedence of %ws."),
514 SETASC(toklev
[j
], lev
);
520 * TRANSLATION_NOTE -- This is a message from yacc.
521 * This message is passed to error() function.
523 "redeclaration of type of %ws"),
525 SETTYPE(toklev
[j
], ty
);
527 if ((t
= gettok()) == NUMBER
) {
528 tokset
[j
].value
= numbval
;
529 if (j
< ndefout
&& j
> 2) {
531 * TRANSLATION_NOTE -- This is a message from yacc.
532 * This message is passed to error() function.
535 "type number of %ws should be defined earlier"),
538 if (numbval
>= -YYFLAG1
) {
540 * TRANSLATION_NOTE -- This is a message from yacc.
541 * This message is passed to error() function.
544 "token numbers must be less than %d"),
554 * TRANSLATION_NOTE -- This is a message from yacc.
555 * This message is passed to error() function.
558 "missing tokens or illegal tokens"));
570 error("syntax error");
578 * TRANSLATION_NOTE -- This is a message from yacc.
579 * This message is passed to error() function.
580 * Do not translate %%%%.
582 error("unexpected EOF before %%%%");
588 end_toks(); /* all tokens dumped - get ready for reductions */
590 (void) fprintf(ftable
, "\n#include <inttypes.h>\n");
591 (void) fprintf(ftable
, "\n#ifdef __STDC__\n");
592 (void) fprintf(ftable
, "#include <stdlib.h>\n");
593 (void) fprintf(ftable
, "#include <string.h>\n");
594 (void) fprintf(ftable
, "#define YYCONST const\n");
595 (void) fprintf(ftable
, "#else\n");
596 (void) fprintf(ftable
, "#include <malloc.h>\n");
597 (void) fprintf(ftable
, "#include <memory.h>\n");
598 (void) fprintf(ftable
, "#define YYCONST\n");
599 (void) fprintf(ftable
, "#endif\n");
600 (void) fprintf(ftable
, "\n#include <values.h>\n");
602 if (sym_prefix
[0] != '\0')
603 put_prefix_define(sym_prefix
);
605 (void) fprintf(ftable
,
606 "\n#if defined(__cplusplus) || defined(__STDC__)\n");
607 (void) fprintf(ftable
,
608 "\n#if defined(__cplusplus) && defined(__EXTERN_C__)\n");
609 (void) fprintf(ftable
, "extern \"C\" {\n");
610 (void) fprintf(ftable
, "#endif\n");
611 (void) fprintf(ftable
, "#ifndef yyerror\n");
612 (void) fprintf(ftable
, "#if defined(__cplusplus)\n");
613 (void) fprintf(ftable
, " void yyerror(YYCONST char *);\n");
614 (void) fprintf(ftable
, "#endif\n");
615 (void) fprintf(ftable
, "#endif\n");
616 (void) fprintf(ftable
, "#ifndef yylex\n");
617 (void) fprintf(ftable
, " int yylex(void);\n");
618 (void) fprintf(ftable
, "#endif\n");
619 (void) fprintf(ftable
, " int yyparse(void);\n");
620 (void) fprintf(ftable
,
621 "#if defined(__cplusplus) && defined(__EXTERN_C__)\n");
622 (void) fprintf(ftable
, "}\n");
623 (void) fprintf(ftable
, "#endif\n");
624 (void) fprintf(ftable
, "\n#endif\n\n");
626 (void) fprintf(ftable
, "#define yyclearin yychar = -1\n");
627 (void) fprintf(ftable
, "#define yyerrok yyerrflag = 0\n");
628 (void) fprintf(ftable
, "extern int yychar;\nextern int yyerrflag;\n");
629 if (!(defunion
|| ntypes
))
630 (void) fprintf(ftable
,
631 "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
632 (void) fprintf(ftable
, "YYSTYPE yylval;\n");
633 (void) fprintf(ftable
, "YYSTYPE yyval;\n");
634 (void) fprintf(ftable
, "typedef int yytabelem;\n");
635 (void) fprintf(ftable
,
636 "#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n");
637 (void) fprintf(ftable
, "#if YYMAXDEPTH > 0\n");
638 (void) fprintf(ftable
, "int yy_yys[YYMAXDEPTH], *yys = yy_yys;\n");
639 (void) fprintf(ftable
, "YYSTYPE yy_yyv[YYMAXDEPTH], *yyv = yy_yyv;\n");
640 (void) fprintf(ftable
, "#else /* user does initial allocation */\n");
641 (void) fprintf(ftable
, "int *yys;\nYYSTYPE *yyv;\n#endif\n");
642 (void) fprintf(ftable
, "static int yymaxdepth = YYMAXDEPTH;\n");
645 /* added production */
648 /* if start is 0, we will overwrite with the lhs of the first rule */
654 while ((t
= gettok()) == LCURLY
)
657 if (t
!= C_IDENTIFIER
)
658 error("bad syntax on first rule");
661 prdptr
[0][1] = chfind(1, tokname
);
665 while (t
!= MARK
&& t
!= ENDFILE
) {
670 rhsfill((wchar_t *)0); /* restart fill of rhs */
671 *mem
= *prdptr
[nprod
-1];
672 if (++mem
>= &tracemem
[new_memsize
])
674 } else if (t
== C_IDENTIFIER
) {
675 *mem
= chfind(1, tokname
);
678 * TRANSLATION_NOTE -- This is a message from yacc.
679 * This message is passed to error() function.
680 * Check how nonterminal is translated.
683 "illegal nonterminal in grammar rule"));
684 if (++mem
>= &tracemem
[new_memsize
])
686 lhsfill(tokname
); /* new rule: restart strings */
689 * TRANSLATION_NOTE -- This is a message from yacc.
690 * This message is passed to error() function.
693 "illegal rule: missing semicolon or | ?"));
700 while (t
== IDENTIFIER
) {
701 *mem
= chfind(1, tokname
);
703 levprd
[nprod
] = toklev
[*mem
]& ~04;
704 if (++mem
>= &tracemem
[new_memsize
])
706 rhsfill(tokname
); /* add to rhs string */
711 if (gettok() != IDENTIFIER
)
713 * TRANSLATION_NOTE -- This is a message from yacc.
714 * This message is passed to error() function.
715 * Do not translate %%prec.
718 "illegal %%prec syntax"));
719 j
= chfind(2, tokname
);
722 * TRANSLATION_NOTE -- This is a message from yacc.
723 * This message is passed to error() function.
724 * Do not translate %%prec.
727 "nonterminal %ws illegal after %%prec"),
728 nontrst
[j
-NTBASE
].name
);
729 levprd
[nprod
] = toklev
[j
] & ~04;
735 levprd
[nprod
] |= ACTFLAG
;
736 (void) fprintf(faction
, "\ncase %d:", nprod
);
737 cpyact(mem
-prdptr
[nprod
] - 1);
738 (void) fprintf(faction
, " break;");
739 if ((t
= gettok()) == IDENTIFIER
) {
740 /* action within rule... */
742 lrprnt(); /* dump lhs, rhs */
743 (void) wsprintf(actname
, "$$%d", nprod
);
745 * make it nonterminal
747 j
= chfind(1, actname
);
750 * the current rule will become rule
751 * number nprod+1 move the contents down,
752 * and make room for the null
755 if (mem
+ 2 >= &tracemem
[new_memsize
])
757 for (p
= mem
; p
>= prdptr
[nprod
]; --p
)
761 /* enter null production for action */
768 /* update the production information */
770 levprd
[nprod
+1] = levprd
[nprod
] & ~ACTFLAG
;
771 levprd
[nprod
] = ACTFLAG
;
773 if (++nprod
>= nprodsz
)
778 * make the action appear in
782 if (mem
>= &tracemem
[new_memsize
])
784 /* get some more of the rule */
791 if (mem
>= &tracemem
[new_memsize
])
794 /* check that default action is reasonable */
796 if (ntypes
&& !(levprd
[nprod
] & ACTFLAG
) &&
797 nontrst
[*prdptr
[nprod
]-NTBASE
].tvalue
) {
798 /* no explicit action, LHS has value */
800 tempty
= prdptr
[nprod
][1];
803 * TRANSLATION_NOTE -- This is a message from yacc.
804 * This message is passed to error() function.
805 * LHS means Left Hand Side. It does not need to be translated.
808 "must return a value, since LHS has a type"));
809 else if (tempty
>= NTBASE
)
810 tempty
= nontrst
[tempty
-NTBASE
].tvalue
;
812 tempty
= TYPE(toklev
[tempty
]);
813 if (tempty
!= nontrst
[*prdptr
[nprod
]-NTBASE
].tvalue
) {
815 * TRANSLATION_NOTE -- This is a message from yacc.
816 * This message is passed to error() function.
817 * Check how action is transltated in yacc man page or documents.
820 "default action causes potential type clash"));
824 if (++nprod
>= nprodsz
)
829 /* end of all rules */
831 end_debug(); /* finish fdebug file's input */
835 (void) fprintf(ftable
, "\n# line %d \"%s\"\n",
837 while ((c
= getwc(finput
)) != EOF
)
838 (void) putwc(c
, ftable
);
840 (void) fclose(finput
);
846 /* finish action routine */
847 (void) fclose(faction
);
848 (void) fprintf(ftable
, "# define YYERRCODE %d\n", tokset
[2].value
);
857 static int used_save
= 0;
858 static int exp_cname
= CNAMSZ
;
863 * Don't need to expand the table, just allocate new space.
866 while (len
>= (exp_cname
- used_save
)) {
869 free((char *)cnames
);
870 if ((cnames
= (wchar_t *)
871 malloc(sizeof (wchar_t)*exp_cname
)) == NULL
)
873 * TRANSLATION_NOTE -- This is a message from yacc.
874 * This message is passed to error() function.
876 * You may just translate this as:
877 * 'Could not allocate internally used memory.'
880 "cannot expand string dump"));
889 used
+= cnamp
- temp
;
894 defin(int t
, wchar_t *s
)
896 /* define s to be a terminal if t=0 or a nonterminal if t=1 */
901 if (++nnonter
>= nnontersz
)
903 nontrst
[nnonter
].name
= cstash(s
);
904 return (NTBASE
+ nnonter
);
906 /* must be a token */
907 if (++ntokens
>= ntoksz
)
909 tokset
[ntokens
].name
= cstash(s
);
911 /* establish value for token */
913 if (s
[0] == L
' ' && s
[2] == 0) { /* single character literal */
914 val
= findchtok(s
[1]);
915 } else if (s
[0] == L
' ' && s
[1] == L
'\\') { /* escape sequence */
916 if (s
[3] == 0) { /* single character escape sequence */
918 /* character which is escaped */
920 (void) warning(1, gettext(
922 * TRANSLATION_NOTE -- This is a message from yacc.
923 * This message is passed to warning() function.
924 * Do not trasnlate ANSI C, \\a.
926 "\\a is ANSI C \"alert\" character"));
927 #if __STDC__ - 1 == 0
934 case L
'v': val
= L
'\v'; break;
935 case L
'n': val
= L
'\n'; break;
936 case L
'r': val
= L
'\r'; break;
937 case L
'b': val
= L
'\b'; break;
938 case L
't': val
= L
'\t'; break;
939 case L
'f': val
= L
'\f'; break;
940 case L
'\'': val
= L
'\''; break;
941 case L
'"': val
= L
'"'; break;
942 case L
'?': val
= L
'?'; break;
943 case L
'\\': val
= L
'\\'; break;
945 * TRANSLATION_NOTE -- This is a message from yacc.
946 * This message is passed to error() function.
948 default: error(gettext(
951 } else if (s
[2] <= L
'7' && s
[2] >= L
'0') { /* \nnn sequence */
954 while (iswdigit(s
[i
]) && i
<= 4) {
955 if (s
[i
] >= L
'0' && s
[i
] <= L
'7')
956 val
= val
* 8 + s
[i
] - L
'0';
959 * TRANSLATION_NOTE -- This is a message from yacc.
960 * This message is passed to error() function.
963 "illegal octal number"));
968 * TRANSLATION_NOTE -- This is a message from yacc.
969 * This message is passed to error() function.
970 * Do not translate \\nnn.
973 "illegal \\nnn construction"));
976 * TRANSLATION_NOTE -- This is a message from yacc.
977 * This message is passed to error() function.
979 * \\nnn, \\xnnnnnnnn.
982 "\\nnn exceed \\377; use \\xnnnnnnnn for wchar_t value of multibyte char");
983 if (val
== 0 && i
>= 4)
985 * TRANSLATION_NOTE -- This is a message from yacc.
986 * This message is passed to error() function.
987 * Do not translate \\000.
990 "'\\000' is illegal"));
991 } else if (s
[2] == L
'x') { /* hexadecimal \xnnn sequence */
995 * TRANSLATION_NOTE -- This is a message from yacc.
996 * This message is passed to warning() function.
997 * Do not translate \\x, ANSI C.
999 (void) warning(1, gettext(
1000 "\\x is ANSI C hex escape"));
1001 if (iswxdigit(s
[i
]))
1002 while (iswxdigit(s
[i
])) {
1005 tmpval
= s
[i
] - L
'0';
1006 else if (s
[i
] >= L
'a')
1007 tmpval
= s
[i
] - L
'a' + 10;
1009 tmpval
= s
[i
] - L
'A' + 10;
1010 val
= 16 * val
+ tmpval
;
1015 "illegal hexadecimal number"));
1018 * TRANSLATION_NOTE -- This is a message from yacc.
1019 * This message is passed to error() function.
1020 * Do not translate \\xnn.
1023 "illegal \\xnn construction"));
1024 #define LWCHAR_MAX 0x7fffffff
1025 if ((unsigned)val
> LWCHAR_MAX
)
1027 * TRANSLATION_NOTE -- This is a message from yacc.
1028 * This message is passed to error() function.
1029 * Do not translate \\xnnnnnnnn and %#x.
1032 " \\xnnnnnnnn exceed %#x"),
1036 * TRANSLATION_NOTE -- This is a message from yacc.
1037 * This message is passed to error() function.
1038 * Do not translate \\x00.
1041 "'\\x00' is illegal"));
1042 val
= findchtok(val
);
1049 tokset
[ntokens
].value
= val
;
1050 toklev
[ntokens
] = 0;
1057 /* write out the defines (at the end of the declaration section) */
1060 register wchar_t *cp
;
1062 for (i
= ndefout
; i
<= ntokens
; ++i
) {
1064 cp
= tokset
[i
].name
;
1065 if (*cp
== L
' ') /* literals */
1067 (void) fprintf(fdebug
, WSFMT("\t\"%ws\",\t%d,\n"),
1068 tokset
[i
].name
+ 1, tokset
[i
].value
);
1069 continue; /* was cp++ */
1072 for (; (c
= *cp
) != 0; ++cp
) {
1073 if (iswlower(c
) || iswupper(c
) ||
1074 iswdigit(c
) || c
== L
'_')
1080 (void) fprintf(fdebug
,
1081 WSFMT("\t\"%ws\",\t%d,\n"), tokset
[i
].name
,
1083 (void) fprintf(ftable
,
1084 WSFMT("# define %ws %d\n"), tokset
[i
].name
,
1086 if (fdefine
!= NULL
)
1087 (void) fprintf(fdefine
,
1088 WSFMT("# define %ws %d\n"),
1094 ndefout
= ntokens
+1;
1101 static int peekline
; /* number of '\n' seen in lookahead */
1102 int c
, match
, reserve
;
1109 * while (c == ' ' || c == '\n' || c == '\t' || c == '\f') {
1111 while (iswspace(c
)) {
1116 if (c
== L
'/') { /* skip comment */
1117 lineno
+= skipcom();
1126 (void) ungetwc(c
, finput
);
1127 return (L
'='); /* action ... */
1128 case L
'<': /* get, and look up, a type name (union member name) */
1130 while ((c
= getwc(finput
)) != L
'>' &&
1131 c
!= EOF
&& c
!= L
'\n') {
1138 "unterminated < ... > clause"));
1141 error("missing type name in < ... > clause");
1142 for (i
= 1; i
<= ntypes
; ++i
) {
1143 if (!wscmp(typeset
[i
], tokname
)) {
1148 typeset
[numbval
= ++ntypes
] = cstash(tokname
);
1158 if (c
== L
'\n' || c
== EOF
)
1160 "illegal or missing ' or \""));
1166 } else if (c
== match
) break;
1176 switch (c
= getwc(finput
)) {
1178 case L
'0': return (TERM
);
1179 case L
'<': return (LEFT
);
1180 case L
'2': return (BINARY
);
1181 case L
'>': return (RIGHT
);
1183 case L
'\\': return (MARK
);
1184 case L
'=': return (PREC
);
1185 case L
'{': return (LCURLY
);
1186 default: reserve
= 1;
1191 if (iswdigit(c
)) { /* number */
1193 base
= (c
== L
'0') ? 8 : 10;
1194 for (c
= getwc(finput
);
1196 c
= getwc(finput
)) {
1197 numbval
= numbval
*base
+ c
- L
'0';
1199 (void) ungetwc(c
, finput
);
1201 } else if (iswlower(c
) || iswupper(c
) ||
1202 c
== L
'_' || c
== L
'.' ||
1205 while (iswlower(c
) || iswupper(c
) ||
1206 iswdigit(c
) || c
== L
'_' ||
1207 c
== L
'.' || c
== L
'$') {
1209 if (reserve
&& iswupper(c
))
1210 tokname
[i
] = towlower(c
);
1219 (void) ungetwc(c
, finput
);
1224 if (reserve
) { /* find a reserved word */
1225 if (!wscmp(tokname
, L
"term"))
1227 if (!wscmp(tokname
, L
"token"))
1229 if (!wscmp(tokname
, L
"left"))
1231 if (!wscmp(tokname
, L
"nonassoc"))
1233 if (!wscmp(tokname
, L
"binary"))
1235 if (!wscmp(tokname
, L
"right"))
1237 if (!wscmp(tokname
, L
"prec"))
1239 if (!wscmp(tokname
, L
"start"))
1241 if (!wscmp(tokname
, L
"type"))
1243 if (!wscmp(tokname
, L
"union"))
1246 "invalid escape, or illegal reserved word: %ws"),
1250 /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
1254 * while (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '/')
1257 while (iswspace(c
) || c
== L
'/') {
1260 } else if (c
== L
'/') { /* look for comments */
1261 peekline
+= skipcom();
1266 return (C_IDENTIFIER
);
1267 (void) ungetwc(c
, finput
);
1268 return (IDENTIFIER
);
1274 /* determine the type of a symbol */
1277 v
= nontrst
[t
-NTBASE
].tvalue
;
1279 v
= TYPE(toklev
[t
]);
1282 "must specify type for %ws"),
1283 (t
>= NTBASE
) ? nontrst
[t
-NTBASE
].name
:
1289 chfind(int t
, wchar_t *s
)
1296 if (!wscmp(s
, tokset
[i
].name
)) {
1301 if (!wscmp(s
, nontrst
[i
].name
)) {
1302 return (i
+ NTBASE
);
1305 /* cannot find name */
1308 "%ws should have been defined earlier"), s
);
1309 return (defin(t
, s
));
1316 * copy the union declaration to the output,
1317 * and the define file if present
1321 (void) fprintf(ftable
, "\n# line %d \"%s\"\n", lineno
, infile
);
1322 (void) fprintf(ftable
, "typedef union\n");
1324 (void) fprintf(fdefine
, "\ntypedef union\n");
1325 (void) fprintf(ftable
, "#ifdef __cplusplus\n\tYYSTYPE\n#endif\n");
1327 (void) fprintf(fdefine
,
1328 "#ifdef __cplusplus\n\tYYSTYPE\n#endif\n");
1332 if ((c
= getwc(finput
)) == EOF
)
1334 * TRANSLATION_NOTE -- This is a message from yacc.
1335 * This message is passed to error() function.
1336 * EOF - End Of File.
1337 * Do not translate %%union.
1340 "EOF encountered while processing %%union"));
1341 (void) putwc(c
, ftable
);
1343 (void) putwc(c
, fdefine
);
1357 if (level
== 0) { /* we are finished copying */
1358 (void) fprintf(ftable
, " YYSTYPE;\n");
1360 (void) fprintf(fdefine
,
1361 " YYSTYPE;\nextern YYSTYPE yylval;\n");
1371 /* copies code between \{ and \} */
1380 (void) fprintf(ftable
, "\n# line %d \"%s\"\n", lineno
, infile
);
1383 if ((c
= getwc(finput
)) == L
'}')
1386 (void) putwc(L
'\\', ftable
);
1387 } else if (c
== L
'%') {
1388 if ((c
= getwc(finput
)) == L
'}')
1391 (void) putwc(L
'%', ftable
);
1393 (void) putwc(c
, ftable
);
1399 * TRANSLATION_NOTE -- This is a message from yacc.
1400 * This message is passed to error() function.
1401 * Do not translate %%}.
1410 /* skip over comments */
1411 int c
, i
= 0; /* i is the number of lines skipped */
1413 /* skipcom is called after reading a / */
1415 if (getwc(finput
) != L
'*')
1417 "illegal comment"));
1421 if ((c
= getwc(finput
)) == L
'/')
1429 * TRANSLATION_NOTE -- This is a message from yacc.
1430 * This message is passed to error() function.
1431 * EOF -- End Of File.
1434 "EOF inside comment"));
1442 /* copy C action to the next ; or closing } */
1443 int brac
, c
, match
, i
, t
, j
, s
, tok
, argument
, m
;
1444 wchar_t id_name
[NAMESIZE
+1];
1448 (void) fprintf(faction
, "\n# line %d \"%s\"\n", lineno
, infile
);
1459 (void) putwc(c
, faction
);
1470 while ((c
= getwc(finput
)) == L
' ' || c
== L
'\t')
1472 if (c
== L
'<') { /* type description */
1473 (void) ungetwc(c
, finput
);
1474 if (gettok() != TYPENAME
)
1476 * TRANSLATION_NOTE -- This is a message from yacc.
1477 * This message is passed to error() function.
1478 * Do not translate $<ident>
1481 "bad syntax on $<ident> clause"));
1486 (void) fprintf(faction
, "yyval");
1487 if (ntypes
) { /* put out the proper tag... */
1489 tok
= fdtype(*prdptr
[nprod
]);
1490 (void) fprintf(faction
,
1491 WSFMT(".%ws"), typeset
[tok
]);
1498 (void) ungetwc(c
, finput
);
1499 if (gettok() != IDENTIFIER
)
1501 * TRANSLATION_NOTE -- This is a message from yacc.
1502 * This message is passed to error() function.
1503 * Check how action is translated in yacc man page/document.
1506 "bad action format"));
1508 * Save the number of non-terminal
1511 t
= chfind(1, tokname
);
1513 * Check if the identifier is added as a non-terminal
1515 if (id_sw
!= nnonter
)
1519 while ((c
= getwc(finput
)) == L
' ' ||
1523 while ((c
= getwc(finput
)) == L
' ' ||
1528 while (iswdigit(c
)) {
1535 "illegal character \"#\""));
1539 * TRANSLATION_NOTE -- This is a message from yacc.
1540 * This message is passed to error() function.
1541 * Check how action is translated in yacc man page/document.
1544 "illegal action argument no."));
1545 for (i
= 1; i
<= offset
; ++i
)
1546 if (prdptr
[nprod
][i
] == t
)
1547 if (++same
== argument
) {
1548 (void) fprintf(faction
,
1549 "yypvt[-%d]", offset
-i
);
1554 fdtype(prdptr
[nprod
][i
]);
1555 (void) fprintf(faction
,
1562 * This used to be handled as error.
1563 * Treat this as a valid C statement.
1564 * (Likely id with $ in.)
1565 * If non-terminal is added, remove it from the list.
1567 (void) fprintf(faction
, WSFMT("$%ws"), tokname
);
1569 * TRANSLATION_NOTE -- This is a message from yacc.
1570 * This message is passed to warning() function.
1571 * Do not translate Ansi C.
1574 "Illegal character '$' in Ansi C symbol: %ws$%ws."),
1587 while (iswdigit(c
)) {
1588 j
= j
*10 + c
- L
'0';
1594 * TRANSLATION_NOTE -- This is a message from yacc.
1595 * This message is passed to error() function.
1596 * Do not translate $%d.
1599 "Illegal use of $%d"),
1602 (void) fprintf(faction
, "yypvt[-%d]", -j
);
1603 if (ntypes
) { /* put out the proper tag */
1604 if (j
+ offset
<= 0 && tok
< 0)
1606 * TRANSLATION_NOTE -- This is a message from yacc.
1607 * This message is passed to error() function.
1608 * Do not translate $%d.
1611 "must specify type of $%d"),
1614 tok
= fdtype(prdptr
[nprod
][j
+offset
]);
1615 (void) fprintf(faction
,
1616 WSFMT(".%ws"), typeset
[tok
]);
1620 (void) putwc(L
'$', faction
);
1622 (void) putwc(L
'-', faction
);
1627 (void) putwc(c
, faction
);
1629 case L
'/': /* look for comments */
1630 (void) putwc(c
, faction
);
1634 /* it really is a comment */
1635 (void) putwc(c
, faction
);
1639 (void) putwc(c
, faction
);
1640 if ((c
= getwc(finput
)) == L
'/')
1643 (void) putwc(c
, faction
);
1648 error("EOF inside comment");
1650 case L
'\'': /* character constant */
1651 case L
'"': /* character string */
1653 (void) putwc(c
, faction
);
1654 while ((c
= getwc(finput
)) != EOF
) {
1656 (void) putwc(c
, faction
);
1660 } else if (c
== match
)
1662 else if (c
== L
'\n')
1664 * TRANSLATION_NOTE -- This is a message from yacc.
1665 * This message is passed to error() function.
1666 * This error message is issued when
1667 * quoted string has multiple lines.
1670 "newline in string or char. const."));
1671 (void) putwc(c
, faction
);
1674 "EOF in string or character constant"));
1678 * TRANSLATION_NOTE -- This is a message from yacc.
1679 * This message is passed to error() function.
1680 * Check how 'action' is translated in yacc mapage/document.
1683 "action does not terminate"));
1690 (void) putwc(c
, faction
);
1692 * Save the possible identifier name.
1693 * Used to print out a warning message.
1695 if (id_idx
>= NAMESIZE
) {
1697 * Error. Silently ignore.
1702 * If c has a possibility to be a
1703 * part of identifier, save it.
1705 else if (iswalnum(c
) || c
== L
'_') {
1706 id_name
[id_idx
++] = c
;
1707 id_name
[id_idx
] = 0;
1710 id_name
[id_idx
] = 0;
1716 lhsfill(s
) /* new rule, dump old (if exists), restart strings */
1719 static int lhs_len
= LHS_TEXT_LEN
;
1720 int s_lhs
= wslen(s
);
1721 if (s_lhs
>= lhs_len
) {
1722 lhs_len
= s_lhs
+ 2;
1723 lhstext
= (wchar_t *)
1724 realloc((char *)lhstext
, sizeof (wchar_t)*lhs_len
);
1725 if (lhstext
== NULL
)
1727 * TRANSLATION_NOTE -- This is a message from yacc.
1728 * This message is passed to error() function.
1729 * LHS -- Left Hand Side.
1732 "couldn't expanded LHS length"));
1734 rhsfill((wchar_t *)0);
1735 (void) wscpy(lhstext
, s
); /* don't worry about too long of a name */
1740 wchar_t *s
; /* either name or 0 */
1742 static wchar_t *loc
; /* next free location in rhstext */
1743 static int rhs_len
= RHS_TEXT_LEN
;
1744 static int used
= 0;
1745 int s_rhs
= (s
== NULL
? 0 : wslen(s
));
1746 register wchar_t *p
;
1748 if (!s
) /* print out and erase old text */
1750 if (*lhstext
) /* there was an old rule - dump it */
1752 (loc
= rhstext
)[0] = 0;
1755 /* add to stuff in rhstext */
1758 used
= loc
- rhstext
;
1759 if ((s_rhs
+ 3) >= (rhs_len
- used
)) {
1760 static wchar_t *textbase
;
1762 rhs_len
+= s_rhs
+ RHS_TEXT_LEN
;
1763 rhstext
= (wchar_t *)
1764 realloc((char *)rhstext
, sizeof (wchar_t)*rhs_len
);
1765 if (rhstext
== NULL
)
1767 * TRANSLATION_NOTE -- This is a message from yacc.
1768 * This message is passed to error() function.
1769 * RHS -- Right Hand Side.
1772 "couldn't expanded RHS length"));
1773 loc
= loc
- textbase
+ rhstext
;
1777 if (*s
== L
' ') /* special quoted symbol */
1779 *loc
++ = L
'\''; /* add first quote */
1783 if (loc
++ > &rhstext
[ RHS_TEXT_LEN
] - 3)
1788 *loc
= 0; /* terminate the string */
1792 lrprnt() /* print out the left and right hand sides */
1795 wchar_t *m_rhs
= NULL
;
1797 if (!*rhstext
) /* empty rhs - print usual comment */
1798 rhs
= L
" /* empty */";
1800 int idx1
; /* tmp idx used to find if there are d_quotes */
1801 int idx2
; /* tmp idx used to generate escaped string */
1804 * Check if there are any double quote in RHS.
1806 for (idx1
= 0; rhstext
[idx1
] != 0; idx1
++) {
1807 if (rhstext
[idx1
] == L
'"') {
1809 * A double quote is found.
1811 idx2
= wslen(rhstext
)*2;
1812 p
= m_rhs
= (wchar_t *)
1813 malloc((idx2
+ 1)*sizeof (wchar_t));
1816 * TRANSLATION_NOTE -- This is a message from yacc.
1817 * This message is passed to error() function.
1818 * RHS - Right Hand Side.
1820 * You may just translate this as:
1821 * 'Could not allocate internally used memory.'
1824 "Couldn't allocate memory for RHS."));
1828 for (idx2
= 0; rhstext
[idx2
] != 0; idx2
++) {
1830 * Check if this quote is escaped or not
1832 if (rhstext
[idx2
] == L
'"') {
1835 while (tmp_l
>= 0 &&
1836 rhstext
[tmp_l
] == '\\') {
1841 * If quote is not escaped,
1847 *p
++ = rhstext
[idx2
];
1851 * Break from the loop
1861 (void) fprintf(fdebug
, WSFMT("\t\"%ws :%ws\",\n"), lhstext
, rhs
);
1868 beg_debug() /* dump initial sequence for fdebug file */
1870 (void) fprintf(fdebug
,
1871 "typedef struct\n");
1872 (void) fprintf(fdebug
,
1873 "#ifdef __cplusplus\n\tyytoktype\n");
1874 (void) fprintf(fdebug
, "#endif\n{\n");
1875 (void) fprintf(fdebug
,
1876 "#ifdef __cplusplus\nconst\n#endif\n");
1877 (void) fprintf(fdebug
, "char *t_name; int t_val; } yytoktype;\n");
1878 (void) fprintf(fdebug
,
1879 "#ifndef YYDEBUG\n#\tdefine YYDEBUG\t%d", gen_testing
);
1880 (void) fprintf(fdebug
, "\t/*%sallow debugging */\n#endif\n\n",
1881 gen_testing
? " " : " don't ");
1882 (void) fprintf(fdebug
, "#if YYDEBUG\n\nyytoktype yytoks[] =\n{\n");
1887 end_toks() /* finish yytoks array, get ready for yyred's strings */
1889 (void) fprintf(fdebug
, "\t\"-unknown-\",\t-1\t/* ends search */\n");
1890 (void) fprintf(fdebug
, "};\n\n");
1891 (void) fprintf(fdebug
,
1892 "#ifdef __cplusplus\nconst\n#endif\n");
1893 (void) fprintf(fdebug
, "char * yyreds[] =\n{\n");
1894 (void) fprintf(fdebug
, "\t\"-no such reduction-\",\n");
1899 end_debug() /* finish yyred array, close file */
1901 lrprnt(); /* dump last lhs, rhs */
1902 (void) fprintf(fdebug
, "};\n#endif /* YYDEBUG */\n");
1903 (void) fclose(fdebug
);
1909 * The normal length for token sizes is NAMESIZE - If a token is
1910 * seen that has a longer length, expand "tokname" by NAMESIZE.
1915 toksize
+= NAMESIZE
;
1916 tokname
= (wchar_t *)
1917 realloc((char *)tokname
, sizeof (wchar_t) * toksize
);
1931 prdptr
= (int **) realloc((char *)prdptr
, sizeof (int *) * (nprodsz
+2));
1932 levprd
= (int *) realloc((char *)levprd
, sizeof (int) * (nprodsz
+2));
1933 had_act
= (wchar_t *)
1934 realloc((char *)had_act
, sizeof (wchar_t) * (nprodsz
+2));
1935 for (i
= nprodsz
-NPROD
; i
< nprodsz
+2; ++i
)
1938 if ((*prdptr
== NULL
) || (levprd
== NULL
) || (had_act
== NULL
))
1940 * TRANSLATION_NOTE -- This is a message from yacc.
1941 * This message is passed to error() function.
1943 * You may just translate this as:
1944 * 'Could not allocate internally used memory.'
1947 "couldn't expand productions"));
1952 * Expand the number of terminals. Initially there are NTERMS;
1953 * each time space runs out, the size is increased by NTERMS.
1954 * The total size, however, cannot exceed MAXTERMS because of
1955 * the way LOOKSETS(struct looksets) is set up.
1957 * tokset, toklev : increased to ntoksz
1959 * tables with initial dimensions of TEMPSIZE must be changed if
1960 * (ntoksz + NNONTERM) >= TEMPSIZE : temp1[]
1967 tokset
= (TOKSYMB
*) realloc((char *)tokset
, sizeof (TOKSYMB
) * ntoksz
);
1968 toklev
= (int *) realloc((char *)toklev
, sizeof (int) * ntoksz
);
1970 if ((tokset
== NULL
) || (toklev
== NULL
))
1972 * TRANSLATION_NOTE -- This is a message from yacc.
1973 * This message is passed to error() function.
1974 * Do not translate NTERMS.
1976 * You may just translate this as:
1977 * 'Could not allocate internally used memory.'
1980 "couldn't expand NTERMS"));
1987 nnontersz
+= NNONTERM
;
1989 nontrst
= (NTSYMB
*)
1990 realloc((char *)nontrst
, sizeof (TOKSYMB
) * nnontersz
);
1991 if (nontrst
== NULL
)
1993 * TRANSLATION_NOTE -- This is a message from yacc.
1994 * This message is passed to error() function.
1995 * Do not translate NTERMS.
1997 * You may just translate this as:
1998 * 'Could not allocate internally used memory.'
2001 "couldn't expand NNONTERM"));
2009 static int *membase
;
2010 new_memsize
+= MEMSIZE
;
2014 realloc((char *)tracemem
, sizeof (int) * new_memsize
);
2015 if (tracemem
== NULL
)
2017 * TRANSLATION_NOTE -- This is a message from yacc.
2018 * This message is passed to error() function.
2020 * You may just translate this as:
2021 * 'Could not allocate internally used memory.'
2024 "couldn't expand mem table"));
2026 for (i
= 0; i
<= nprod
; ++i
)
2027 prdptr
[i
] = prdptr
[i
] - membase
+ tracemem
;
2028 mem
= mem
- membase
+ tracemem
;
2031 temp1
= (int *)realloc((char *)temp1
, sizeof (int)*size
);
2032 optimmem
= optimmem
- membase
+ tracemem
;
2040 * findchtok(chlit) returns the token number for a character literal
2041 * chlit that is "bigger" than 255 -- the max char value that the
2042 * original yacc was build for. This yacc treate them as though
2043 * an ordinary token.
2049 return (chlit
); /* single-byte char */
2050 for (i
= 0; i
< nmbchars
; ++i
) {
2051 if (mbchars
->character
== chlit
)
2052 return (mbchars
->tvalue
);
2055 /* Not found. Register it! */
2056 if (++nmbchars
> nmbcharsz
) { /* Make sure there's enough space */
2057 nmbcharsz
+= NMBCHARSZ
;
2058 mbchars
= (MBCLIT
*)
2059 realloc((char *)mbchars
, sizeof (MBCLIT
)*nmbcharsz
);
2060 if (mbchars
== NULL
)
2062 "too many character literals"));
2064 mbchars
[nmbchars
-1].character
= chlit
;
2065 return (mbchars
[nmbchars
-1].tvalue
= extval
++);
2066 /* Return the newly assigned token. */
2070 * When -p is specified, symbol prefix for
2071 * yy{parse, lex, error}(),
2072 * yy{lval, val, char, debug, errflag, nerrs}
2073 * are defined to the specified name.
2076 put_prefix_define(char *pre
)
2093 for (i
= 0; syms
[i
]; i
++)
2094 (void) fprintf(ftable
, "#define\tyy%s\t%s%s\n",
2095 syms
[i
], pre
, syms
[i
]);