4 static char rcsid
[] = "$Id: gram.y 145 2001-10-17 21:53:10Z timo $";
5 /*lint -e616 -e527 -e652 -esym(552,yynerrs) -esym(563,yynewstate,yyerrlab) */
6 static int yylineno
= 0;
17 %token
<string> ID TEMPLATE CODE
19 %type
<string> nonterm cost
22 spec
: decls PPERCENT rules
{ yylineno
= 0; }
23 | decls
{ yylineno
= 0; }
30 decl
: TERMINAL blist
'\n'
31 | START nonterm
'\n' {
32 if
(nonterm
($2)->number
!= 1)
33 yyerror("redeclaration of the start symbol\n");
36 |
error '\n' { yyerrok; }
40 | blist ID
'=' INT
{ term
($2, $4); }
44 | rules nonterm
':' tree TEMPLATE cost
'\n' { rule
($2, $4, $5, $6); }
46 | rules
error '\n' { yyerrok; }
49 nonterm
: ID
{ nonterm
($$
= $1); }
52 tree
: ID
{ $$
= tree
($1, 0, 0); }
53 | ID
'(' tree
')' { $$
= tree
($1, $3, 0); }
54 | ID
'(' tree
',' tree
')' { $$
= tree
($1, $3, $5); }
57 cost
: CODE
{ if
(*$1 == 0) $$
= "0"; }
69 static char buf
[BUFSIZ
], *bp
= buf
;
70 static int ppercent
= 0;
73 static int get
(void) {
77 if
(fgets
(buf
, sizeof buf
, infp
) == NULL
)
80 while
(buf
[0] == '%' && buf
[1] == '{' && buf
[2] == '\n') {
82 if
(fgets
(buf
, sizeof buf
, infp
) == NULL
) {
83 yywarn
("unterminated %{...%}\n");
87 if
(strcmp
(buf
, "%}\n") == 0)
91 if
(fgets
(buf
, sizeof buf
, infp
) == NULL
)
99 void yyerror(char *fmt
, ...
) {
104 fprintf
(stderr
, "line %d: ", yylineno
);
105 vfprintf
(stderr
, fmt
, ap
);
106 if
(fmt
[strlen
(fmt
)-1] != '\n')
107 fprintf
(stderr
, "\n");
117 bp
+= strspn
(bp
, " \t\f");
118 p
= strchr
(bp
, '\n');
120 p
= strchr
(bp
, '\n');
121 while
(p
> bp
&& isspace
(p
[-1]))
123 yylval.
string = alloc
(p
- bp
+ 1);
124 strncpy
(yylval.
string, bp
, p
- bp
);
125 yylval.
string[p
- bp
] = 0;
130 while
((c
= get
()) != EOF
) {
132 case
' ': case
'\f': case
'\t':
135 case
'(': case
')': case
',':
139 if
(c
== '%' && *bp
== '%') {
141 return ppercent
++ ?
0 : PPERCENT
;
142 } else if
(c
== '%' && strncmp
(bp
, "term", 4) == 0
146 } else if
(c
== '%' && strncmp
(bp
, "start", 5) == 0
150 } else if
(c
== '"') {
151 char *p
= strchr
(bp
, '"');
153 yyerror("missing \" in assembler template\n");
154 p
= strchr
(bp
, '\n');
156 p
= strchr
(bp
, '\0');
159 yylval.
string = alloc
(p
- bp
+ 1);
160 strncpy
(yylval.
string, bp
, p
- bp
);
161 yylval.
string[p
- bp
] = 0;
162 bp
= *p
== '"' ? p
+ 1 : p
;
165 } else if
(isdigit
(c
)) {
169 if
(n
> (INT_MAX
- d
)/10)
170 yyerror("integer greater than %d\n", INT_MAX
);
174 } while
(c
!= EOF
&& isdigit
(c
));
178 } else if
(isalpha
(c
)) {
180 while
(isalpha
(*bp
) || isdigit
(*bp
) ||
*bp
== '_')
182 yylval.
string = alloc
(bp
- p
+ 1);
183 strncpy
(yylval.
string, p
, bp
- p
);
184 yylval.
string[bp
- p
] = 0;
186 } else if
(isprint
(c
))
187 yyerror("invalid character `%c'\n", c
);
189 yyerror("invalid character `\\%03o'\n", (unsigned char)c
);
194 void yywarn
(char *fmt
, ...
) {
199 fprintf
(stderr
, "line %d: ", yylineno
);
200 fprintf
(stderr
, "warning: ");
201 vfprintf
(stderr
, fmt
, ap
);