ack/util/mcgg/gram.y

183 lines
3.3 KiB
Text
Raw Normal View History

2016-09-20 18:37:16 +00:00
%{
#include <string.h>
#include <stdio.h>
#include <limits.h>
#include "iburg.h"
#define YYDEBUG 1
2016-09-20 18:37:16 +00:00
static char rcsid[] = "$Id$";
static int nextesn = 0;
static int nextern = 0;
2016-09-20 18:37:16 +00:00
%}
%union {
int n;
char* string;
2016-09-20 18:37:16 +00:00
Tree tree;
Stringlist stringlist;
2016-09-24 10:11:30 +00:00
char* stringpair[2];
2016-09-20 18:37:16 +00:00
}
%term TERMINAL
%term START
%term PPERCENT
%term PATTERNS
%term WHEN
%term EMIT
%term FRAGMENT
%term COST
%term INS
%term OUTS
2016-09-24 10:11:30 +00:00
%token <n> INT
%token <string> ID
%token <string> CFRAGMENT
%token <string> STRING
%type <n> cost
2016-09-24 10:11:30 +00:00
%type <string> lhs
%type <stringlist> stringlist
2016-09-24 10:11:30 +00:00
%type <stringlist> when
%type <tree> rhs
%type <stringpair> labelledid
2016-09-20 18:37:16 +00:00
%%
spec
: decls PPERCENT patterns
| decls
2016-09-20 18:37:16 +00:00
;
decls : /* lambda */
| decls decl
;
decl
: TERMINAL blist ';'
| START lhs ';'
{
if (nonterm($2)->number != 1)
yyerror("redeclaration of the start symbol\n");
}
| ';'
| error ';' { yyerrok; }
2016-09-20 18:37:16 +00:00
;
blist
: /* nothing */
| blist ID { term($2, nextesn++); }
;
2016-09-20 18:37:16 +00:00
patterns
: /* nothing */
| patterns pattern ';'
| patterns ';'
| patterns error ';' { yyerrok; }
2016-09-20 18:37:16 +00:00
;
pattern
: lhs '=' rhs when ins outs emits cost { rule($1, $3, nextern++, $4, $8); }
;
lhs
: ID { $$ = $1; nonterm($$); }
2016-09-20 18:37:16 +00:00
;
rhs
2016-09-24 10:11:30 +00:00
: labelledid { $$ = tree($1[1], $1[0], NULL, NULL); }
| labelledid '(' rhs ')' { $$ = tree($1[1], $1[0], $3, NULL); }
| labelledid '(' rhs ',' rhs ')' { $$ = tree($1[1], $1[0], $3, $5); }
2016-09-20 18:37:16 +00:00
;
2016-09-24 10:11:30 +00:00
labelledid
: ID { $$[0] = NULL; $$[1] = $1; }
| ID ':' ID { $$[0] = $1; $$[1] = $3; }
2016-09-24 10:11:30 +00:00
;
when
: /* nothing */ { $$ = NULL; }
| WHEN stringlist { $$ = $2; }
;
stringlist
: /* nothing */ { $$ = NULL; }
| CFRAGMENT stringlist { $$ = pushstring($1, $2); }
;
ins
: /* nothing */
| INS inslist
;
inslist
: inslist ',' in
| in
;
in
: ID ':' ID
;
outs
: /* nothing */
| OUTS outslist
;
outslist
: outslist ',' out
| out
;
out
: ID ':' ID
;
emits
: /* nothing */
| EMIT STRING
| FRAGMENT STRING
;
cost
: /* lambda */ { $$ = 0; }
| COST INT {
if ($2 > maxcost) {
yyerror("%d exceeds maximum cost of %d\n", $2, maxcost);
$$ = maxcost;
} else
$$ = $2;
}
2016-09-20 18:37:16 +00:00
;
%%
#include <stdarg.h>
#include <ctype.h>
int errcnt = 0;
FILE *infp = NULL;
FILE *outfp = NULL;
static char buf[BUFSIZ], *bp = buf;
static int ppercent = 0;
void yyerror(char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
if (yylineno > 0)
fprintf(stderr, "line %d: ", yylineno);
vfprintf(stderr, fmt, ap);
if (fmt[strlen(fmt)-1] != '\n')
fprintf(stderr, "\n");
errcnt++;
}
void yywarn(char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
if (yylineno > 0)
fprintf(stderr, "line %d: ", yylineno);
fprintf(stderr, "warning: ");
vfprintf(stderr, fmt, ap);
}
/* vim: set sw=4 ts=4 expandtab : */