2016-09-20 18:37:16 +00:00
|
|
|
%{
|
2016-09-25 10:18:39 +00:00
|
|
|
#include <stdlib.h>
|
2016-09-20 18:37:16 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2016-09-24 22:21:46 +00:00
|
|
|
#include <stdbool.h>
|
2016-09-29 20:32:43 +00:00
|
|
|
#include <stdint.h>
|
2016-09-20 18:37:16 +00:00
|
|
|
#include <limits.h>
|
|
|
|
#include "iburg.h"
|
2016-09-20 22:43:10 +00:00
|
|
|
|
|
|
|
#define YYDEBUG 1
|
|
|
|
|
2016-09-24 22:21:46 +00:00
|
|
|
extern int yylex(void);
|
|
|
|
|
2016-09-24 17:03:55 +00:00
|
|
|
static int nextern = 1;
|
2016-09-20 22:43:10 +00:00
|
|
|
|
2016-09-20 18:37:16 +00:00
|
|
|
%}
|
|
|
|
%union {
|
|
|
|
int n;
|
2016-09-20 22:43:10 +00:00
|
|
|
char* string;
|
2016-09-25 20:17:14 +00:00
|
|
|
Nonterm nonterm;
|
2016-09-20 18:37:16 +00:00
|
|
|
Tree tree;
|
2016-09-24 17:03:55 +00:00
|
|
|
Rule rule;
|
2016-09-25 20:17:14 +00:00
|
|
|
struct reg* reg;
|
2016-09-25 10:18:39 +00:00
|
|
|
struct stringlist* stringlist;
|
2016-09-24 10:11:30 +00:00
|
|
|
char* stringpair[2];
|
2016-09-20 18:37:16 +00:00
|
|
|
}
|
|
|
|
|
2016-09-25 20:17:14 +00:00
|
|
|
%term ALLOCATES
|
|
|
|
%term COST
|
|
|
|
%term DECLARATIONS
|
2016-09-20 22:43:10 +00:00
|
|
|
%term EMIT
|
2016-09-24 11:08:17 +00:00
|
|
|
%term FRAGMENT
|
|
|
|
%term INS
|
|
|
|
%term OUTS
|
2016-09-25 20:17:14 +00:00
|
|
|
%term PATTERNS
|
|
|
|
%term REGISTERS
|
|
|
|
%term WHEN
|
2016-09-20 22:43:10 +00:00
|
|
|
|
2016-09-24 10:11:30 +00:00
|
|
|
%token <n> INT
|
2016-09-20 22:43:10 +00:00
|
|
|
%token <string> ID
|
|
|
|
%token <string> CFRAGMENT
|
2016-09-24 22:21:46 +00:00
|
|
|
%token <string> QFRAGMENT
|
2016-09-20 22:43:10 +00:00
|
|
|
|
2016-09-25 20:17:14 +00:00
|
|
|
%type <nonterm> allocates
|
|
|
|
%type <nonterm> declaration
|
|
|
|
%type <reg> register
|
2016-09-24 22:21:46 +00:00
|
|
|
%type <rule> emit
|
2016-09-25 20:17:14 +00:00
|
|
|
%type <rule> pattern
|
2016-09-24 22:21:46 +00:00
|
|
|
%type <stringlist> cfragments
|
|
|
|
%type <stringlist> qfragments
|
2016-09-24 10:11:30 +00:00
|
|
|
%type <stringpair> labelledid
|
2016-09-25 20:17:14 +00:00
|
|
|
%type <tree> rhs
|
2016-09-20 18:37:16 +00:00
|
|
|
%%
|
2016-09-24 22:21:46 +00:00
|
|
|
|
2016-09-20 22:43:10 +00:00
|
|
|
spec
|
2016-09-25 20:17:14 +00:00
|
|
|
: REGISTERS registers
|
|
|
|
DECLARATIONS declarations
|
|
|
|
PATTERNS patterns
|
2016-09-20 18:37:16 +00:00
|
|
|
;
|
|
|
|
|
2016-09-25 20:17:14 +00:00
|
|
|
registers
|
|
|
|
: /* nothing */
|
|
|
|
| registers register ';'
|
|
|
|
| register ';'
|
|
|
|
;
|
|
|
|
|
|
|
|
register
|
|
|
|
: ID { $$ = makereg($1); }
|
|
|
|
| register ID { $$ = $1; addregclass($1, $2); }
|
|
|
|
;
|
|
|
|
|
|
|
|
declarations
|
|
|
|
: /* nothing */
|
|
|
|
| declarations declaration ';'
|
|
|
|
| declaration ';'
|
|
|
|
;
|
|
|
|
|
|
|
|
declaration
|
|
|
|
: ID { $$ = nonterm($1, true); }
|
|
|
|
| declaration FRAGMENT { $$ = $1; $$->is_fragment = true; }
|
|
|
|
| allocates { $$ = $1; }
|
|
|
|
;
|
|
|
|
|
|
|
|
allocates
|
|
|
|
: declaration ALLOCATES '(' ID ')'
|
|
|
|
{
|
|
|
|
$$ = $1;
|
|
|
|
if ($$->allocate)
|
|
|
|
yyerror("pattern type is defined to already allocate a register");
|
|
|
|
$$->allocate = getregclass($4);
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
2016-09-20 22:43:10 +00:00
|
|
|
patterns
|
|
|
|
: /* nothing */
|
|
|
|
| patterns pattern ';'
|
|
|
|
| patterns ';'
|
2016-09-20 18:37:16 +00:00
|
|
|
;
|
|
|
|
|
2016-09-20 22:43:10 +00:00
|
|
|
pattern
|
2016-09-25 20:17:14 +00:00
|
|
|
: ID '=' rhs { nonterm($1, false); $$ = rule($1, $3, nextern++); }
|
|
|
|
| rhs { $$ = rule("stmt", $1, nextern++); }
|
2016-09-25 10:18:39 +00:00
|
|
|
| pattern WHEN cfragments { $$ = $1; stringlist_addall(&$$->when, $3); }
|
2016-09-24 22:21:46 +00:00
|
|
|
| emit { $$ = $1; }
|
2016-09-24 17:03:55 +00:00
|
|
|
| pattern COST INT { $$ = $1; $$->cost = $3; }
|
2016-09-20 22:43:10 +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
|
2016-09-24 11:08:17 +00:00
|
|
|
: ID { $$[0] = NULL; $$[1] = $1; }
|
|
|
|
| ID ':' ID { $$[0] = $1; $$[1] = $3; }
|
2016-09-24 10:11:30 +00:00
|
|
|
;
|
|
|
|
|
2016-09-24 22:21:46 +00:00
|
|
|
cfragments
|
2016-09-25 10:18:39 +00:00
|
|
|
: /* nothing */ { $$ = calloc(1, sizeof *$$); }
|
|
|
|
| cfragments CFRAGMENT { $$ = $1; stringlist_add($$, $2); }
|
2016-09-20 22:43:10 +00:00
|
|
|
;
|
|
|
|
|
2016-09-24 22:21:46 +00:00
|
|
|
emit
|
2016-09-25 10:18:39 +00:00
|
|
|
: pattern EMIT qfragments {
|
|
|
|
$$ = $1;
|
2016-09-25 20:17:14 +00:00
|
|
|
if (!$$->lhs->is_fragment)
|
|
|
|
stringlist_add($3, "\n");
|
2016-09-25 10:18:39 +00:00
|
|
|
stringlist_addall(&$$->code, $3);
|
|
|
|
}
|
2016-09-24 22:21:46 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
qfragments
|
2016-09-25 20:17:14 +00:00
|
|
|
: /* nothing */ { $$ = calloc(1, sizeof *$$); }
|
|
|
|
| qfragments QFRAGMENT { $$ = $1; stringlist_add($$, $2); }
|
2016-09-24 11:08:17 +00:00
|
|
|
;
|
|
|
|
|
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);
|
|
|
|
}
|
2016-09-20 22:43:10 +00:00
|
|
|
|
|
|
|
/* vim: set sw=4 ts=4 expandtab : */
|