Better ANSI C compatibility and portability:
+ Addition of function prototypes and include files. + Change function definitions to ANSI C style. + Initial support for CMake
This commit is contained in:
parent
cc27fd471d
commit
d825e962ed
28
util/topgen/CMakeLists.txt
Normal file
28
util/topgen/CMakeLists.txt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
cmake_minimum_required (VERSION 3.2)
|
||||||
|
project(em_topgen)
|
||||||
|
set(SRC
|
||||||
|
main.c
|
||||||
|
topgen.c
|
||||||
|
Lpars.c
|
||||||
|
LLlex.c
|
||||||
|
symtab.c
|
||||||
|
symtab.h
|
||||||
|
pattern.c
|
||||||
|
hash.c
|
||||||
|
token.h
|
||||||
|
tunable.h
|
||||||
|
)
|
||||||
|
set(INCLUDE_DIRS
|
||||||
|
.
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT topgen.c Lpars.c Lpars.h
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E env LLGEN_LIB_DIR=${CMAKE_CURRENT_SOURCE_DIR}/../LLgen/lib ${CMAKE_CURRENT_BINARY_DIR}/../LLgen/LLgen "${CMAKE_CURRENT_SOURCE_DIR}/topgen.g"
|
||||||
|
# COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../LLgen/llgen "${CMAKE_CURRENT_SOURCE_DIR}/topgen.g"
|
||||||
|
MAIN_DEPENDENCY topgen.g
|
||||||
|
DEPENDS LLgen)
|
||||||
|
add_executable(topgen ${SRC})
|
||||||
|
target_include_directories(topgen PRIVATE ${INCLUDE_DIRS})
|
||||||
|
target_link_libraries(topgen)
|
||||||
|
install(TARGETS topgen DESTINATION bin)
|
|
@ -21,8 +21,11 @@ static struct token aside; /* to put currrent token aside, when a token
|
||||||
int newline, lineno; /* To keep track of linenumbers */
|
int newline, lineno; /* To keep track of linenumbers */
|
||||||
extern FILE *input; /* file descriptor of machine table */
|
extern FILE *input; /* file descriptor of machine table */
|
||||||
|
|
||||||
LLlex() {
|
extern void error(char *s, char* s1);
|
||||||
register c;
|
|
||||||
|
|
||||||
|
int LLlex(void) {
|
||||||
|
register int c;
|
||||||
|
|
||||||
if (aside.t_tokno) { /* A token was pushed aside, return it now */
|
if (aside.t_tokno) { /* A token was pushed aside, return it now */
|
||||||
dot = aside;
|
dot = aside;
|
||||||
|
@ -52,7 +55,7 @@ LLlex() {
|
||||||
if (c == EOF) {
|
if (c == EOF) {
|
||||||
c = lineno;
|
c = lineno;
|
||||||
lineno = l;
|
lineno = l;
|
||||||
error("Unterminated comment");
|
error("Unterminated comment", "");
|
||||||
lineno = c;
|
lineno = c;
|
||||||
c = EOF;
|
c = EOF;
|
||||||
}
|
}
|
||||||
|
@ -116,13 +119,14 @@ LLlex() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LLmessage(d) {
|
void LLmessage(int d)
|
||||||
|
{
|
||||||
static int savlineno;
|
static int savlineno;
|
||||||
|
|
||||||
if (savlineno != lineno) {
|
if (savlineno != lineno) {
|
||||||
/* Only an error message if on another line number */
|
/* Only an error message if on another line number */
|
||||||
savlineno = lineno;
|
savlineno = lineno;
|
||||||
error("Syntax error");
|
error("Syntax error","");
|
||||||
}
|
}
|
||||||
if (d > 0) {
|
if (d > 0) {
|
||||||
/* "d" is the token to be inserted.
|
/* "d" is the token to be inserted.
|
||||||
|
|
|
@ -8,83 +8,89 @@
|
||||||
* maintains the the lists of hashed patterns
|
* maintains the the lists of hashed patterns
|
||||||
* Functions : addtohashtable() and printhashtable()
|
* Functions : addtohashtable() and printhashtable()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
struct hlist { /* linear list of pattern numbers */
|
struct hlist
|
||||||
int h_patno;
|
{ /* linear list of pattern numbers */
|
||||||
struct hlist *h_next;
|
int h_patno;
|
||||||
|
struct hlist *h_next;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct hlist *hashtable[129]; /* an array of ptr's to these lists,
|
static struct hlist *hashtable[129]; /* an array of ptr's to these lists,
|
||||||
* the index in the array is the
|
* the index in the array is the
|
||||||
* result of hashing
|
* result of hashing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static unsigned
|
static unsigned hash(char* string)
|
||||||
hash(string) char *string; {
|
{
|
||||||
register char *p;
|
register char *p;
|
||||||
register unsigned i,sum;
|
register unsigned i, sum;
|
||||||
|
|
||||||
if (strcmp(string,"ANY") == 0) return 128;
|
if (strcmp(string, "ANY") == 0)
|
||||||
for (sum=i=0,p=string;*p;i += 3)
|
return 128;
|
||||||
sum += (*p++)<<(i&03);
|
for (sum = i = 0, p = string; *p; i += 3)
|
||||||
|
sum += (*p++) << (i & 03);
|
||||||
return sum % 128;
|
return sum % 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addtohashtable(char* s, int n)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Add a new pattern number to the hashtable.
|
||||||
|
* s is the key, n the pattern number
|
||||||
|
*/
|
||||||
|
unsigned hval;
|
||||||
|
register struct hlist *p;
|
||||||
|
|
||||||
addtohashtable(s,n) char *s; {
|
hval = hash(s);
|
||||||
/*
|
p = (struct hlist *) malloc(sizeof *p);
|
||||||
* Add a new pattern number to the hashtable.
|
p->h_patno = n;
|
||||||
* s is the key, n the pattern number
|
/*
|
||||||
*/
|
* Now insert in front of the list
|
||||||
unsigned hval;
|
* This way, the list will be sorted from high to low, which is the
|
||||||
register struct hlist *p;
|
* wrong way around, but easy
|
||||||
|
*/
|
||||||
hval = hash(s);
|
p->h_next = hashtable[hval];
|
||||||
p = (struct hlist *) malloc(sizeof *p);
|
hashtable[hval] = p;
|
||||||
p->h_patno = n;
|
|
||||||
/*
|
|
||||||
* Now insert in front of the list
|
|
||||||
* This way, the list will be sorted from high to low, which is the
|
|
||||||
* wrong way around, but easy
|
|
||||||
*/
|
|
||||||
p->h_next = hashtable[hval];
|
|
||||||
hashtable[hval] = p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static void prhlist(struct hlist *p)
|
||||||
prhlist(p) struct hlist *p; {
|
{
|
||||||
/*
|
/*
|
||||||
* Print a list in reversed order (see comment above)
|
* Print a list in reversed order (see comment above)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (p) {
|
if (p)
|
||||||
prhlist(p->h_next);
|
{
|
||||||
fprintf(genc,"%d, ",p->h_patno - 1);
|
prhlist(p->h_next);
|
||||||
}
|
fprintf(genc, "%d, ", p->h_patno - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printhashtable() {
|
|
||||||
/*
|
|
||||||
* Print the linear lists, and also output an array of
|
|
||||||
* pointers to them
|
|
||||||
*/
|
|
||||||
register i;
|
|
||||||
register struct hlist *p;
|
|
||||||
|
|
||||||
for (i = 1; i <= 128; i++) {
|
void printhashtable(void)
|
||||||
fprintf(genc,"int hash%d[] = { ",i);
|
{
|
||||||
prhlist(hashtable[i-1]);
|
/*
|
||||||
fputs("-1};\n",genc);
|
* Print the linear lists, and also output an array of
|
||||||
}
|
* pointers to them
|
||||||
fputs("int hashany[] = { ", genc);
|
*/
|
||||||
prhlist(hashtable[128]);
|
register int i;
|
||||||
fputs("-1 };\n",genc);
|
|
||||||
fputs("int *hashtab[] = {\n",genc);
|
for (i = 1; i <= 128; i++)
|
||||||
for (i = 1; i <= 128; i++) fprintf(genc,"\thash%d,\n",i);
|
{
|
||||||
fputs("\thashany\n};\n",genc);
|
fprintf(genc, "int hash%d[] = { ", i);
|
||||||
|
prhlist(hashtable[i - 1]);
|
||||||
|
fputs("-1};\n", genc);
|
||||||
|
}
|
||||||
|
fputs("int hashany[] = { ", genc);
|
||||||
|
prhlist(hashtable[128]);
|
||||||
|
fputs("-1 };\n", genc);
|
||||||
|
fputs("int *hashtab[] = {\n", genc);
|
||||||
|
for (i = 1; i <= 128; i++)
|
||||||
|
fprintf(genc, "\thash%d,\n", i);
|
||||||
|
fputs("\thashany\n};\n", genc);
|
||||||
}
|
}
|
||||||
|
|
23
util/topgen/hash.h
Normal file
23
util/topgen/hash.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* hash.h
|
||||||
|
*
|
||||||
|
* Created on: 2018-11-24
|
||||||
|
* Author: carl
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __HASH_H_INCLUDED__
|
||||||
|
#define __HASH_H_INCLUDED__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a new pattern number to the hashtable.
|
||||||
|
* s is the key, n the pattern number
|
||||||
|
*/
|
||||||
|
void addtohashtable(char* s, int n);
|
||||||
|
/*
|
||||||
|
* Print the linear lists, and also output an array of
|
||||||
|
* pointers to them
|
||||||
|
*/
|
||||||
|
void printhashtable(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __HASH_H_INCLUDED__ */
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "Lpars.h"
|
||||||
|
|
||||||
extern int lineno, newline;
|
extern int lineno, newline;
|
||||||
|
|
||||||
|
@ -19,8 +20,10 @@ static int nerrors;
|
||||||
char *linedir = "#line %d \"%s\"\n"; /* format of line directive */
|
char *linedir = "#line %d \"%s\"\n"; /* format of line directive */
|
||||||
char *inpfile;
|
char *inpfile;
|
||||||
|
|
||||||
main(argc,argv) char *argv[]; {
|
extern void LLparse(void);
|
||||||
|
|
||||||
|
int main(int argc,char* argv[])
|
||||||
|
{
|
||||||
newline = 1;
|
newline = 1;
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
fprintf(stderr,"Usage : %s targetoptimizerdescription outputdir\n",argv[0]);
|
fprintf(stderr,"Usage : %s targetoptimizerdescription outputdir\n",argv[0]);
|
||||||
|
@ -48,15 +51,16 @@ main(argc,argv) char *argv[]; {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VARARGS1 */
|
/* VARARGS1 */
|
||||||
error(s, s1) char *s, *s1; {
|
void error(char *s, char* s1)
|
||||||
|
{
|
||||||
nerrors++;
|
nerrors++;
|
||||||
fprintf(stderr,"\"%s\", line %d: ",inpfile,lineno);
|
fprintf(stderr,"\"%s\", line %d: ",inpfile,lineno);
|
||||||
fprintf(stderr,s,s1);
|
fprintf(stderr,s,s1);
|
||||||
putc('\n',stderr);
|
putc('\n',stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
onlyspace(s) register char *s; {
|
int onlyspace(register char* s)
|
||||||
|
{
|
||||||
|
|
||||||
while (*s) {
|
while (*s) {
|
||||||
if (*s != ' ' && *s != '\t' && *s != '\n') return 0;
|
if (*s != ' ' && *s != '\t' && *s != '\n') return 0;
|
||||||
|
|
|
@ -32,7 +32,8 @@ static struct pattern *pattable, /* ptr to pattern array */
|
||||||
* be allocated
|
* be allocated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
addpattern(str,l,np,nr) char *str; {
|
void addpattern(char* str,int l,int np,int nr)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Just add a pattern to the list.
|
* Just add a pattern to the list.
|
||||||
* "str" is the constraint, "l" is the line number,
|
* "str" is the constraint, "l" is the line number,
|
||||||
|
@ -62,8 +63,8 @@ addpattern(str,l,np,nr) char *str; {
|
||||||
p->p_nrepl = nr;
|
p->p_nrepl = nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static void prconstraint(char* str)
|
||||||
prconstraint(str) char *str; {
|
{
|
||||||
/*
|
/*
|
||||||
* prints a constraint, with variable names replaced
|
* prints a constraint, with variable names replaced
|
||||||
*/
|
*/
|
||||||
|
@ -104,13 +105,13 @@ prconstraint(str) char *str; {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printpatterns() {
|
void printpatterns(void) {
|
||||||
/*
|
/*
|
||||||
* Prints the pattern_descr table and generates the routine
|
* Prints the pattern_descr table and generates the routine
|
||||||
* "check_constraint"
|
* "check_constraint"
|
||||||
*/
|
*/
|
||||||
register struct pattern *p;
|
register struct pattern *p;
|
||||||
register i;
|
register int i;
|
||||||
|
|
||||||
p = pattable;
|
p = pattable;
|
||||||
i = 1;
|
i = 1;
|
||||||
|
@ -127,7 +128,7 @@ printpatterns() {
|
||||||
while (p < current) {
|
while (p < current) {
|
||||||
if (p->p_constraint) {
|
if (p->p_constraint) {
|
||||||
/* The pattern has a constraint */
|
/* The pattern has a constraint */
|
||||||
fprintf(genc,"\tcase %d :\n",p - pattable);
|
fprintf(genc,"\tcase %d :\n",(int)(p - pattable));
|
||||||
fprintf(genc,linedir,p->p_lineno,inpfile); /* linedirective */
|
fprintf(genc,linedir,p->p_lineno,inpfile); /* linedirective */
|
||||||
fputs("\tr = (",genc);
|
fputs("\tr = (",genc);
|
||||||
prconstraint(p->p_constraint);
|
prconstraint(p->p_constraint);
|
||||||
|
|
27
util/topgen/pattern.h
Normal file
27
util/topgen/pattern.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* pattern.h
|
||||||
|
*
|
||||||
|
* Created on: 2018-11-25
|
||||||
|
* Author: carl
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PATTERN_H_INCLUDED__
|
||||||
|
#define __PATTERN_H_INCLUDED__
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Just add a pattern to the list.
|
||||||
|
* "str" is the constraint, "l" is the line number,
|
||||||
|
* "np" is the number of instructions in the pattern,
|
||||||
|
* "nr" is the number of instructions in the replacement
|
||||||
|
* Space is allocated in chunks of 50
|
||||||
|
*/
|
||||||
|
void addpattern(char* str,int l,int np,int nr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prints the pattern_descr table and generates the routine
|
||||||
|
* "check_constraint"
|
||||||
|
*/
|
||||||
|
void printpatterns(void);
|
||||||
|
|
||||||
|
#endif /* __PATTERN_H_INCLUDED__ */
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
struct symtab *idtable, *deftable;
|
struct symtab *idtable, *deftable;
|
||||||
|
|
||||||
|
extern void error(char *s, char* s1);
|
||||||
|
|
||||||
struct symtab *
|
struct symtab *
|
||||||
findident(s, mode, table) char *s; struct symtab **table; {
|
findident(s, mode, table) char *s; struct symtab **table; {
|
||||||
/*
|
/*
|
||||||
|
@ -24,7 +26,7 @@ findident(s, mode, table) char *s; struct symtab **table; {
|
||||||
* table yet, otherwise an error results
|
* table yet, otherwise an error results
|
||||||
*/
|
*/
|
||||||
register struct symtab *p;
|
register struct symtab *p;
|
||||||
register n;
|
register int n;
|
||||||
|
|
||||||
if (!*table) { /* No entry for this symbol */
|
if (!*table) { /* No entry for this symbol */
|
||||||
if (mode == LOOKING) return (struct symtab *) 0;
|
if (mode == LOOKING) return (struct symtab *) 0;
|
||||||
|
|
|
@ -1,311 +1,320 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
/*
|
/*
|
||||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
/* t o p g e n . g
|
/* t o p g e n . g
|
||||||
*
|
*
|
||||||
* Grammar of optimizer description, and some code generation
|
* Grammar of optimizer description, and some code generation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
%token LETTER, DIGIT, OTHER, SPACE;
|
%token LETTER, DIGIT, OTHER, SPACE;
|
||||||
%token LINE_TERMINATOR, OPERAND_SEPARATOR, INSTRUCTION_SEPARATOR,
|
%token LINE_TERMINATOR, OPERAND_SEPARATOR, INSTRUCTION_SEPARATOR,
|
||||||
PATTERN_SEPARATOR, OPEN_BRACKET, CLOSE_BRACKET;
|
PATTERN_SEPARATOR, OPEN_BRACKET, CLOSE_BRACKET;
|
||||||
%lexical LLlex;
|
%lexical LLlex;
|
||||||
%start LLparse, optim_description;
|
%start LLparse, optim_description;
|
||||||
|
|
||||||
{
|
{
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "hash.h"
|
||||||
char idbuf[BUFSIZ], buf[BUFSIZ];
|
#include "pattern.h"
|
||||||
int countid; /* # of variables */
|
|
||||||
int countpat; /* # of patterns */
|
char idbuf[BUFSIZ], buf[BUFSIZ];
|
||||||
static int patlen; /* Maximum number of instructions in pattern */
|
int countid; /* # of variables */
|
||||||
static int maxoperand; /* Maximum number of operands of instruction */
|
int countpat; /* # of patterns */
|
||||||
extern FILE *input; /* file descriptor of inputfile */
|
static int patlen; /* Maximum number of instructions in pattern */
|
||||||
}
|
static int maxoperand; /* Maximum number of operands of instruction */
|
||||||
|
extern FILE *input; /* file descriptor of inputfile */
|
||||||
optim_description
|
|
||||||
{ struct symtab *p; } :
|
|
||||||
SPACE* parameter_line*
|
|
||||||
{ p = findident("MAXOP",LOOKING,&deftable);
|
extern int onlyspace(char* s);
|
||||||
if (p == 0) maxoperand = 2; /* default */
|
extern void error(char *s, char* s1);
|
||||||
else maxoperand = p->s_num;
|
|
||||||
}
|
|
||||||
separator SPACE* mode_definitions
|
}
|
||||||
separator SPACE* patterns
|
|
||||||
separator
|
optim_description
|
||||||
{ register int c;
|
{ struct symtab *p; } :
|
||||||
fprintf(genc, linedir, lineno, inpfile);
|
SPACE* parameter_line*
|
||||||
while ((c = getc(input)) != EOF) {
|
{ p = findident("MAXOP",LOOKING,&deftable);
|
||||||
putc(c,genc);
|
if (p == 0) maxoperand = 2; /* default */
|
||||||
}
|
else maxoperand = p->s_num;
|
||||||
}
|
}
|
||||||
;
|
separator SPACE* mode_definitions
|
||||||
|
separator SPACE* patterns
|
||||||
parameter_line
|
separator
|
||||||
{ struct symtab *p;} :
|
{ register int c;
|
||||||
identifier
|
fprintf(genc, linedir, lineno, inpfile);
|
||||||
{ p = findident(idbuf,ENTERING,&deftable);}
|
while ((c = getc(input)) != EOF) {
|
||||||
SPACE
|
putc(c,genc);
|
||||||
value
|
}
|
||||||
{ p->s_num = atoi(buf);}
|
}
|
||||||
/* This action in fact only needed for MAXOP */
|
;
|
||||||
LINE_TERMINATOR
|
|
||||||
SPACE*
|
parameter_line
|
||||||
{ fprintf(genh,"#define %s %s\n",p->s_name,buf);}
|
{ struct symtab *p;} :
|
||||||
;
|
identifier
|
||||||
|
{ p = findident(idbuf,ENTERING,&deftable);}
|
||||||
value
|
SPACE
|
||||||
{ char *p1 = buf;} :
|
value
|
||||||
[
|
{ p->s_num = atoi(buf);}
|
||||||
[ OPEN_BRACKET
|
/* This action in fact only needed for MAXOP */
|
||||||
| CLOSE_BRACKET
|
LINE_TERMINATOR
|
||||||
| OPERAND_SEPARATOR
|
SPACE*
|
||||||
| PATTERN_SEPARATOR
|
{ fprintf(genh,"#define %s %s\n",p->s_name,buf);}
|
||||||
| INSTRUCTION_SEPARATOR
|
;
|
||||||
| SPACE
|
|
||||||
| LETTER
|
value
|
||||||
| DIGIT
|
{ char *p1 = buf;} :
|
||||||
| OTHER
|
[
|
||||||
| '%'
|
[ OPEN_BRACKET
|
||||||
]
|
| CLOSE_BRACKET
|
||||||
{ *p1++ = dot.t_attrib;}
|
| OPERAND_SEPARATOR
|
||||||
]*
|
| PATTERN_SEPARATOR
|
||||||
{ *p1 = '\0';}
|
| INSTRUCTION_SEPARATOR
|
||||||
;
|
| SPACE
|
||||||
|
| LETTER
|
||||||
mode_definitions
|
| DIGIT
|
||||||
{ int lin; } :
|
| OTHER
|
||||||
{ fputs("tok_chk(varno) {\n\tint r;\n", genc);
|
| '%'
|
||||||
fputs("\tchar *VAL;\n\n",genc);
|
]
|
||||||
fputs("\tVAL = var[varno].value;\n",genc);
|
{ *p1++ = dot.t_attrib;}
|
||||||
fputs("\tswitch(varno) {\n",genc);
|
]*
|
||||||
}
|
{ *p1 = '\0';}
|
||||||
[
|
;
|
||||||
token_list
|
|
||||||
constraint(&lin)
|
mode_definitions
|
||||||
{ fprintf(genc,linedir,lin,inpfile);
|
{ int lin; } :
|
||||||
fprintf(genc,"\t\tr = (%s); break;\n",buf);
|
{ fputs("tok_chk(varno) {\n\tint r;\n", genc);
|
||||||
}
|
fputs("\tchar *VAL;\n\n",genc);
|
||||||
LINE_TERMINATOR
|
fputs("\tVAL = var[varno].value;\n",genc);
|
||||||
SPACE*
|
fputs("\tswitch(varno) {\n",genc);
|
||||||
]*
|
}
|
||||||
{ fputs("\tdefault :\n\t\tassert(0);\n",genc);
|
[
|
||||||
fputs("\t}\n\treturn r;\n}\n\n",genc);
|
token_list
|
||||||
}
|
constraint(&lin)
|
||||||
;
|
{ fprintf(genc,linedir,lin,inpfile);
|
||||||
|
fprintf(genc,"\t\tr = (%s); break;\n",buf);
|
||||||
token_list :
|
}
|
||||||
new_identifier
|
LINE_TERMINATOR
|
||||||
SPACE*
|
SPACE*
|
||||||
[
|
]*
|
||||||
OPERAND_SEPARATOR
|
{ fputs("\tdefault :\n\t\tassert(0);\n",genc);
|
||||||
SPACE*
|
fputs("\t}\n\treturn r;\n}\n\n",genc);
|
||||||
new_identifier
|
}
|
||||||
SPACE*
|
;
|
||||||
]*
|
|
||||||
;
|
token_list :
|
||||||
|
new_identifier
|
||||||
new_identifier
|
SPACE*
|
||||||
{ struct symtab *p;} :
|
[
|
||||||
identifier
|
OPERAND_SEPARATOR
|
||||||
{ p = findident(idbuf,ENTERING,&idtable);
|
SPACE*
|
||||||
p->s_num = ++countid;
|
new_identifier
|
||||||
fprintf(genc,"\tcase %d:\n", countid);
|
SPACE*
|
||||||
}
|
]*
|
||||||
;
|
;
|
||||||
|
|
||||||
constraint (int *lin;)
|
new_identifier
|
||||||
{ char *p = buf; } :
|
{ struct symtab *p;} :
|
||||||
OPEN_BRACKET
|
identifier
|
||||||
{ *lin = lineno;}
|
{ p = findident(idbuf,ENTERING,&idtable);
|
||||||
[
|
p->s_num = ++countid;
|
||||||
[ LINE_TERMINATOR
|
fprintf(genc,"\tcase %d:\n", countid);
|
||||||
| OPERAND_SEPARATOR
|
}
|
||||||
| PATTERN_SEPARATOR
|
;
|
||||||
| INSTRUCTION_SEPARATOR
|
|
||||||
| LETTER
|
constraint (int *lin;)
|
||||||
| DIGIT
|
{ char *p = buf; } :
|
||||||
| SPACE
|
OPEN_BRACKET
|
||||||
| OTHER
|
{ *lin = lineno;}
|
||||||
| '%'
|
[
|
||||||
]
|
[ LINE_TERMINATOR
|
||||||
{ *p++ = dot.t_attrib;}
|
| OPERAND_SEPARATOR
|
||||||
]*
|
| PATTERN_SEPARATOR
|
||||||
{ *p = '\0';
|
| INSTRUCTION_SEPARATOR
|
||||||
if (onlyspace(buf)) strcpy(buf,"TRUE");
|
| LETTER
|
||||||
}
|
| DIGIT
|
||||||
CLOSE_BRACKET
|
| SPACE
|
||||||
SPACE*
|
| OTHER
|
||||||
;
|
| '%'
|
||||||
|
]
|
||||||
patterns
|
{ *p++ = dot.t_attrib;}
|
||||||
{ int lin;
|
]*
|
||||||
char *constr;
|
{ *p = '\0';
|
||||||
int np, nr;
|
if (onlyspace(buf)) strcpy(buf,"TRUE");
|
||||||
} :
|
}
|
||||||
[
|
CLOSE_BRACKET
|
||||||
{ countpat++;
|
SPACE*
|
||||||
constr = (char *) 0;
|
;
|
||||||
fprintf(genc,"struct instr_descr pat%d[] = {\n",
|
|
||||||
countpat);
|
patterns
|
||||||
}
|
{ int lin;
|
||||||
instruction_list(&np)
|
char *constr;
|
||||||
{ if (np > patlen) patlen = np;
|
int np, nr;
|
||||||
fputs("\n};\n\n",genc);
|
} :
|
||||||
}
|
[
|
||||||
[
|
{ countpat++;
|
||||||
constraint(&lin)
|
constr = (char *) 0;
|
||||||
{ /* Save the constraint, we need it later on */
|
fprintf(genc,"struct instr_descr pat%d[] = {\n",
|
||||||
constr = malloc((unsigned)(strlen(buf)+1));
|
countpat);
|
||||||
strcpy(constr,buf);
|
}
|
||||||
}
|
instruction_list(&np)
|
||||||
]?
|
{ if (np > patlen) patlen = np;
|
||||||
PATTERN_SEPARATOR
|
fputs("\n};\n\n",genc);
|
||||||
{ fprintf(genc,"struct instr_descr rep%d[] = {\n",
|
}
|
||||||
countpat);
|
[
|
||||||
}
|
constraint(&lin)
|
||||||
replacement(&nr)
|
{ /* Save the constraint, we need it later on */
|
||||||
{ fputs("\n};\n\n",genc);}
|
constr = malloc((unsigned)(strlen(buf)+1));
|
||||||
LINE_TERMINATOR
|
strcpy(constr,buf);
|
||||||
SPACE*
|
}
|
||||||
{ addpattern(constr,lin,np,nr);}
|
]?
|
||||||
]*
|
PATTERN_SEPARATOR
|
||||||
{ printhashtable();
|
{ fprintf(genc,"struct instr_descr rep%d[] = {\n",
|
||||||
printpatterns();
|
countpat);
|
||||||
fprintf(genh,"#define NRVARS %d\n",countid);
|
}
|
||||||
fprintf(genh,"#define NRPATTERNS %d\n",countpat);
|
replacement(&nr)
|
||||||
fprintf(genh,"#define MIN_WINDOW_SIZE %d\n",
|
{ fputs("\n};\n\n",genc);}
|
||||||
patlen+3);
|
LINE_TERMINATOR
|
||||||
fclose(genh);
|
SPACE*
|
||||||
}
|
{ addpattern(constr,lin,np,nr);}
|
||||||
;
|
]*
|
||||||
|
{ printhashtable();
|
||||||
instruction_list(int *n;) :
|
printpatterns();
|
||||||
instruction(1)
|
fprintf(genh,"#define NRVARS %d\n",countid);
|
||||||
{ *n = 1;}
|
fprintf(genh,"#define NRPATTERNS %d\n",countpat);
|
||||||
[
|
fprintf(genh,"#define MIN_WINDOW_SIZE %d\n",
|
||||||
INSTRUCTION_SEPARATOR
|
patlen+3);
|
||||||
{ fputs(",\n",genc);}
|
fclose(genh);
|
||||||
SPACE*
|
}
|
||||||
instruction(0)
|
;
|
||||||
{ *n += 1;}
|
|
||||||
]*
|
instruction_list(int *n;) :
|
||||||
;
|
instruction(1)
|
||||||
|
{ *n = 1;}
|
||||||
instruction(int opt;)
|
[
|
||||||
{ int count = 0;} :
|
INSTRUCTION_SEPARATOR
|
||||||
opcode(opt)
|
{ fputs(",\n",genc);}
|
||||||
{ if (strcmp(buf,"ANY") != 0) {
|
SPACE*
|
||||||
fprintf(genc,"\t{\"%s\", {",buf);
|
instruction(0)
|
||||||
}
|
{ *n += 1;}
|
||||||
else fputs("\t{(char *) 0, {",genc);
|
]*
|
||||||
count = 0;
|
;
|
||||||
}
|
|
||||||
[
|
instruction(int opt;)
|
||||||
operand(' ')
|
{ int count = 0;} :
|
||||||
{ count = 1;}
|
opcode(opt)
|
||||||
[
|
{ if (strcmp(buf,"ANY") != 0) {
|
||||||
OPERAND_SEPARATOR
|
fprintf(genc,"\t{\"%s\", {",buf);
|
||||||
{ count++;}
|
}
|
||||||
SPACE*
|
else fputs("\t{(char *) 0, {",genc);
|
||||||
operand(',')
|
count = 0;
|
||||||
]*
|
}
|
||||||
{ if (count > maxoperand) {
|
[
|
||||||
error("Too many operands");
|
operand(' ')
|
||||||
}
|
{ count = 1;}
|
||||||
}
|
[
|
||||||
]?
|
OPERAND_SEPARATOR
|
||||||
{ while (count++ < maxoperand) {
|
{ count++;}
|
||||||
fprintf(genc,"%c{\"\",-1,\"\"}",count == 1 ? ' ' : ',');
|
SPACE*
|
||||||
}
|
operand(',')
|
||||||
putc('}',genc);
|
]*
|
||||||
putc('}',genc);
|
{ if (count > maxoperand) {
|
||||||
}
|
error("Too many operands","");
|
||||||
;
|
}
|
||||||
|
}
|
||||||
opcode(int opt;)
|
]?
|
||||||
{ char *p = buf;} :
|
{ while (count++ < maxoperand) {
|
||||||
[
|
fprintf(genc,"%c{\"\",-1,\"\"}",count == 1 ? ' ' : ',');
|
||||||
[ LETTER
|
}
|
||||||
| DIGIT
|
putc('}',genc);
|
||||||
| OTHER
|
putc('}',genc);
|
||||||
]
|
}
|
||||||
{ *p++ = dot.t_attrib;}
|
;
|
||||||
]+
|
|
||||||
SPACE+
|
opcode(int opt;)
|
||||||
{ *p = '\0';
|
{ char *p = buf;} :
|
||||||
if (opt) addtohashtable(buf,countpat);
|
[
|
||||||
}
|
[ LETTER
|
||||||
;
|
| DIGIT
|
||||||
|
| OTHER
|
||||||
operand(int c;)
|
]
|
||||||
{ register struct symtab *p = 0;} :
|
{ *p++ = dot.t_attrib;}
|
||||||
{ fprintf(genc, "%c{\"", c);}
|
]+
|
||||||
[
|
SPACE+
|
||||||
identifier
|
{ *p = '\0';
|
||||||
{ if (!p) {
|
if (opt) addtohashtable(buf,countpat);
|
||||||
p = findident(idbuf,LOOKING,&idtable);
|
}
|
||||||
if (p) fprintf(genc,"\",%d,\"",p->s_num);
|
;
|
||||||
else fputs(idbuf,genc);
|
|
||||||
}
|
operand(int c;)
|
||||||
else fputs(idbuf,genc);
|
{ register struct symtab *p = 0;} :
|
||||||
}
|
{ fprintf(genc, "%c{\"", c);}
|
||||||
| DIGIT
|
[
|
||||||
{ putc(dot.t_attrib,genc);}
|
identifier
|
||||||
| OTHER
|
{ if (!p) {
|
||||||
{ putc(dot.t_attrib,genc);}
|
p = findident(idbuf,LOOKING,&idtable);
|
||||||
]+
|
if (p) fprintf(genc,"\",%d,\"",p->s_num);
|
||||||
{ if (p) fputs("\"}",genc);
|
else fputs(idbuf,genc);
|
||||||
else fputs("\",0,\"\"}",genc);
|
}
|
||||||
}
|
else fputs(idbuf,genc);
|
||||||
SPACE*
|
}
|
||||||
;
|
| DIGIT
|
||||||
|
{ putc(dot.t_attrib,genc);}
|
||||||
replacement (int *n;)
|
| OTHER
|
||||||
{register i;} :
|
{ putc(dot.t_attrib,genc);}
|
||||||
SPACE*
|
]+
|
||||||
{ *n = 0;}
|
{ if (p) fputs("\"}",genc);
|
||||||
[
|
else fputs("\",0,\"\"}",genc);
|
||||||
instruction(0)
|
}
|
||||||
{ *n = 1;}
|
SPACE*
|
||||||
[
|
;
|
||||||
INSTRUCTION_SEPARATOR
|
|
||||||
{ fputs(",\n", genc);}
|
replacement (int *n;)
|
||||||
SPACE*
|
{register int i;} :
|
||||||
instruction(0)
|
SPACE*
|
||||||
{ *n += 1;}
|
{ *n = 0;}
|
||||||
]*
|
[
|
||||||
| /* empty replacement, but there must be a
|
instruction(0)
|
||||||
* structure initializer anyway
|
{ *n = 1;}
|
||||||
*/
|
[
|
||||||
{ fputs("\t{\"\", {",genc);
|
INSTRUCTION_SEPARATOR
|
||||||
for (i = 0; i < maxoperand; i++) {
|
{ fputs(",\n", genc);}
|
||||||
fprintf(genc, "%c{\"\",-1,\"\"}",i?',':' ');
|
SPACE*
|
||||||
}
|
instruction(0)
|
||||||
fputs("}}",genc);
|
{ *n += 1;}
|
||||||
}
|
]*
|
||||||
]
|
| /* empty replacement, but there must be a
|
||||||
;
|
* structure initializer anyway
|
||||||
|
*/
|
||||||
|
{ fputs("\t{\"\", {",genc);
|
||||||
identifier
|
for (i = 0; i < maxoperand; i++) {
|
||||||
{ char *p = idbuf; } :
|
fprintf(genc, "%c{\"\",-1,\"\"}",i?',':' ');
|
||||||
LETTER
|
}
|
||||||
{ *p++ = dot.t_attrib;}
|
fputs("}}",genc);
|
||||||
[ %while (1)
|
}
|
||||||
LETTER { *p++ = dot.t_attrib;}
|
]
|
||||||
| DIGIT { *p++ = dot.t_attrib;}
|
;
|
||||||
]*
|
|
||||||
{ *p = '\0';}
|
|
||||||
;
|
identifier
|
||||||
|
{ char *p = idbuf; } :
|
||||||
separator :
|
LETTER
|
||||||
'%' '%' SPACE* LINE_TERMINATOR
|
{ *p++ = dot.t_attrib;}
|
||||||
;
|
[ %while (1)
|
||||||
|
LETTER { *p++ = dot.t_attrib;}
|
||||||
|
| DIGIT { *p++ = dot.t_attrib;}
|
||||||
|
]*
|
||||||
|
{ *p = '\0';}
|
||||||
|
;
|
||||||
|
|
||||||
|
separator :
|
||||||
|
'%' '%' SPACE* LINE_TERMINATOR
|
||||||
|
;
|
||||||
|
|
Loading…
Reference in a new issue