Initial revision

This commit is contained in:
kaashoek
1987-11-20 11:12:07 +00:00
parent 9947059dcc
commit 75e0c5f7ed
36 changed files with 2660 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
EM=/proj/em/Work
GFILES = pars.g
OFILES = pars.o Lpars.o lex.yy.o help.o conversion.o
IFILES = -I$(EM)/h -I$(EM)/modules/h
LIBS = $(EM)/modules/lib/liballoc.a\
$(EM)/modules/lib/libprint.a\
$(EM)/modules/lib/libstring.a\
$(EM)/modules/lib/libsystem.a
CC = cc
.c.o :
$(CC) $(IFILES) -c $<
as_parser : dummy $(OFILES)
$(CC) -o as_parser $(OFILES) $(LIBS) -ll
lex.yy.c : table.l
lex table.l
dummy : $(GFILES)
LLgen $(LLOPT) $(GFILES)
touch dummy
Lpars.o : Lpars.h decl.h
pars.o : Lpars.h decl.h
Lpars.o : Lpars.h decl.h
lex.yy.o : Lpars.h decl.h

View File

@@ -0,0 +1,5 @@
#include <em.h>
#include <system.h>
extern File *outfile;
extern arith cur_pos;

View File

@@ -0,0 +1,7 @@
#define Bool int
#define TRUE 1
#define FALSE 0
#define MAX_OPERANDS 4
#define MAX_MNEMONICS 100

View File

@@ -0,0 +1,97 @@
pr_text_with_conversions( str)
char *str;
{
char *ptr, *next_conversion(), *pr_conversion();
while ( ptr = next_conversion( str)) {
/* ptr points to '%'-sign */
*ptr = '\0';
out( "fprint( outfile, \"%s\");", str);
*ptr = '%';
str = pr_conversion( ptr);
}
out( "fprint( outfile, \"%s\");", str);
}
char *next_conversion( str)
char *str;
{
char *match();
while ( *str && *str != '%') {
switch ( *str++) {
case '\'' : str = match( '\'', str) + 1;
break;
case '"' : str = match( '"', str) + 1;
break;
}
}
return( *str == '%' ? str : (char *)0);
}
char *match( c, str)
char c, *str;
{
while ( *str && ( *str != c || *(str-1) == '\\'))
str++;
return( *str ? str : str-1);
}
char *match_bracket( str)
char *str;
/* find ')', but look at nesting '('-')' pairs, return position of ')'.
*/
{
int depth;
char *match();
depth = 1;
while ( *str && depth != 0) {
switch ( *str++) {
case '\'' : str = match( '\'', str+1) + 1;
break;
case '"' : str = match( '"', str+1) + 1;
break;
case '(' : depth++;
break;
case ')' : depth--;
break;
}
}
return( str-1);
}
char *find( c, str)
char c, *str;
{
while ( *str && *str != c)
str++;
return( str);
}
char *pr_conversion( str)
char *str;
/* str points to '%'-sign, returns pointer to first character AFTER the
* conversion
*/
{
char *start, *ptr, *match_bracket(), *find();
start = find( '(', str+1);
*start++ = '\0';
ptr = match_bracket( start);
*ptr = '\0';
if ( *(str+1) == '$')
out( "eval( %s);", start);
else if ( strncmp( str+1, "dist", 4) == 0)
out( "dist( %s);", start);
else
out( "fprint( outfile, \"%%%s\", %s);", str+1, start);
return( ptr+1);
}

View File

@@ -0,0 +1,3 @@
#include <alloc.h>
#include <system.h>
#include "const.h"

View File

@@ -0,0 +1,2 @@
eval : eval.c states.h
cc -o eval eval.c

View File

@@ -0,0 +1,309 @@
#include <stdio.h>
#include <ctype.h>
#include "states.h"
#define is_letter( c) ( isalpha( c) || isdigit( c) || c == '_')
#define save_or_put(c) if(previous_state==TEXT)putchar(c);else *bufptr++=c
main()
{
char buffer[256], *bufptr = buffer;
int c, state = TEXT, previous_state = TEXT, depth = 0;
pr_header();
while ( ( c = getchar()) != EOF)
switch ( state) {
case TEXT :
switch ( c) {
case '/' : state = SLASH;
previous_state = TEXT;
save_or_put( c);
break;
case '"' : state = STRING;
previous_state = TEXT;
save_or_put( c);
break;
case '\'': state = CHAR_CONST;
previous_state = TEXT;
save_or_put( c);
break;
case '@' : state = AT;
break;
default : putchar( c);
break;
}
break;
case SLASH :
state = ( c == '*' ? COMMENT : TEXT);
save_or_put( c);
break;
case COMMENT :
if ( c == '*')
state = STAR;
save_or_put( c);
break;
case STAR :
if ( c == '/')
state = previous_state;
else if ( c != '*')
state = COMMENT;
save_or_put( c);
break;
case STRING :
if ( c == '"')
state = previous_state;
else if ( c == '\\')
state = BACKSLASH_in_STRING;
save_or_put( c);
break;
case BACKSLASH_in_STRING :
state = STRING;
save_or_put( c);
break;
case CHAR_CONST :
if ( c == '\'')
state = previous_state;
else if ( c == '\\')
state = BACKSLASH_in_CHAR_CONST;
save_or_put( c);
break;
case BACKSLASH_in_CHAR_CONST :
state = CHAR_CONST;
save_or_put( c);
break;
case AT : /* @if '(' <CONDITION> ')'
* @elsif '(' <CONDITION> ')'
* @else
* @fi
* @<IDENTIFIER> '(' <PARAM_LIST> ')'
*/
if ( is_letter( c))
*bufptr++ = c;
else {
ungetc( c, stdin);
state = WHITE_SPACE;
}
break;
case WHITE_SPACE :
if ( isspace( c))
*bufptr++ = c;
else if ( c == '(') {
*bufptr++ = c;
depth = 1;
state = CAL_or_QUEST;
}
else {
*bufptr = '\0';
pr_ELSE_or_FI( buffer);
bufptr = buffer;
ungetc( c, stdin);
state = TEXT;
}
break;
case CAL_or_QUEST : /* match ')' */
*bufptr++ =c;
switch ( c) {
case '(' : depth++;
break;
case ')' : depth--;
if ( depth == 0) {
*bufptr = '\0';
pr_CALL_or_QUEST( buffer);
bufptr = buffer;
state = TEXT;
}
break;
case '/' : state = SLASH;
previous_state = CAL_or_QUEST;
break;
case '"' : state = STRING;
previous_state = CAL_or_QUEST;
break;
case '\'': state = CHAR_CONST;
previous_state = CAL_or_QUEST;
break;
}
break;
default :
fprintf( stderr, "Unknown state : %d\n", state);
break;
}
exit( 0);
}
pr_header()
{
printf( "#include \"as_parser.h\"\n");
printf( "#line 1 \"as.c\"\n");
}
pr_ELSE_or_FI( str)
char *str;
{
if ( strncmp( str, "else", 4) == 0)
printf( "fprint( outfile, \"}\else {\");%s", str+4);
else if ( strncmp( str, "fi", 2) == 0)
printf( "fprint( outfile, \"}\");%s", str+2);
else
fprintf( stderr, "%s unexpected!!\n", str);
}
pr_CALL_or_QUEST( str)
char *str;
{
if ( strncmp( str, "if", 2) == 0 && !(is_letter( *(str+2))))
pr_if( str);
else if ( strncmp( str, "elsif", 5) == 0 && !(is_letter( *(str+5))))
pr_elsif( str);
else
pr_call( str);
}
pr_call( call)
char *call;
{
if ( strncmp( "text", call, 4) == 0 && isdigit( *(call+4)))
printf( "cur_pos += %d;", *(call+4) - '0');
else if ( strncmp( "reloc", call, 5) == 0 && isdigit( *(call+5)))
printf( "cur_pos += %d;", *(call+5) - '0');
pr_text_with_conversions( call);
printf( "fprint( outfile, \";\")");
}
pr_elsif( quest)
char *quest;
{
printf( "fprint( outfile, \"}\else if\");");
pr_text_with_conversions( quest+5);
printf( "fprint( outfile, \"{\");");
}
pr_if( quest)
char *quest;
{
pr_text_with_conversions( quest);
printf( "fprint( outfile, \"{\");");
}
pr_text_with_conversions( str)
char *str;
{
char *ptr, *next_conversion(), *pr_conversion();
while ( ptr = next_conversion( str)) {
/* ptr points to '%'-sign */
*ptr = '\0';
printf( "fprint( outfile, \"%s\");", str);
*ptr = '%';
str = pr_conversion( ptr);
}
printf( "fprint( outfile, \"%s\");", str);
}
char *next_conversion( str)
char *str;
{
char *match();
while ( *str && *str != '%') {
switch ( *str++) {
case '\'' : str = match( '\'', str) + 1;
break;
case '"' : str = match( '"', str) + 1;
break;
}
}
return( *str == '%' ? str : (char *)0);
}
char *match( c, str)
char c, *str;
{
while ( *str && ( *str != c || *(str-1) == '\\'))
str++;
return( *str ? str : str-1);
}
char *match_bracket( str)
char *str;
/* find ')', but look at nesting '('-')' pairs, return position of ')'.
*/
{
int depth;
char *match();
depth = 1;
while ( *str && depth != 0) {
switch ( *str++) {
case '\'' : str = match( '\'', str+1) + 1;
break;
case '"' : str = match( '"', str+1) + 1;
break;
case '(' : depth++;
break;
case ')' : depth--;
break;
}
}
return( str-1);
}
char *find( c, str)
char c, *str;
{
while ( *str && *str != c)
str++;
return( str);
}
char *pr_conversion( str)
char *str;
/* str points to '%'-sign, returns pointer to first character AFTER the
* conversion
*/
{
char *start, *ptr, *match_bracket(), *find();
start = find( '(', str+1);
*start++ = '\0';
ptr = match_bracket( start);
*ptr = '\0';
if ( *(str+1) == '$')
printf( "eval( %s);", start);
else if ( strncmp( str+1, "dist", 4) == 0)
printf( "dist( %s);", start);
else
printf( "fprint( outfile, \"%%%s\", %s);", str+1, start);
return( ptr+1);
}

View File

@@ -0,0 +1,11 @@
#define TEXT 1
#define SLASH 2
#define COMMENT 3
#define STAR 4
#define STRING 5
#define BACKSLASH_in_STRING 6
#define CHAR_CONST 7
#define BACKSLASH_in_CHAR_CONST 8
#define AT 9
#define CAL_or_QUEST 10
#define WHITE_SPACE 11

287
util/ceg/as_parser/help.c Normal file
View File

@@ -0,0 +1,287 @@
#include "decl.h"
extern char *strindex();
static struct Op_info { char *name, *type}
op_info[ MAX_OPERANDS] = { { 0, 0}};
static int n_ops = 0;
static char *assem_instr = 0;
static Bool restriction = FALSE;
File *outfile;
save_instr( instr, len)
char *instr;
int len;
{
assem_instr = Salloc( instr, len + 1);
}
save_name( name, len)
char *name;
int len;
{
op_info[ n_ops].name = Salloc( name, len + 1);
}
save_type( type, len)
char *type;
int len;
{
op_info[ n_ops].type = Salloc( type, len + 1);
restriction = TRUE;
}
pr_header()
{
out( "%s_instr", assem_instr);
param_list();
out( "{\n");
save_mnem( assem_instr);
}
param_list()
{
int i;
out( "(");
if ( n_ops > 0) {
out( " %s", op_info[0].name);
for ( i = 1; i < n_ops; i++)
out( ", %s", op_info[i].name);
}
out( ")\n");
if ( n_ops > 0) {
out( "struct t_operand *%s", op_info[0].name);
for ( i = 1; i < n_ops; i++)
out( ", *%s", op_info[i].name);
out( ";\n");
}
}
pr_restriction()
{
int i;
Bool more = FALSE;
if ( !restriction)
return;
out( "if ( ");
for ( i = 0; i < n_ops; i++)
if ( op_info[i].type != 0) {
if ( more)
out( " &&");
out( " %s( %s)", op_info[i].type, op_info[i].name);
more = TRUE;
}
out( ") ");
}
pr_warning()
{
if ( restriction)
out( "else\nerror( \"No match for %s\");\n", assem_instr);
restriction = FALSE;
}
clear_restriction()
{
restriction = FALSE;
}
char *skip_string( str)
char *str;
{
for ( str++; *str != '"' || *(str-1) == '\\'; str++);
return( str + 1);
}
pr_subroutine( str)
char *str;
{
out( "%s;\n", str);
}
#include <ctype.h>
pr_call( str)
char *str;
{
if ( strncmp( "text", str, 4) == 0 && isdigit( *(str+4)))
out( "cur_pos += %d;\n", *(str+4) - '0');
else if ( strncmp( "reloc", str, 5) == 0 && isdigit( *(str+5)))
out( "cur_pos += %d;\n", *(str+5) - '0');
pr_text_with_conversions( str);
out( "fprint( outfile, \";\");");
}
pr_end()
{
out( "fprint( outfile, \"}\\n\");");
}
pr_els()
{
out( "fprint( outfile, \"else\\n\");");
}
pr_else()
{
out( "fprint( outfile, \"else {\\n\");");
}
pr_question( quest)
char *quest;
{
out( "fprint( outfile, \"if\");");
pr_text_with_conversions( quest);
out( "fprint( outfile, \"{\\n\");");
}
init_table()
{
outfile = STDOUT;
out( "#include \"as.h\"\n");
out( "#include \"as_parser.h\"\n");
}
clean()
{
int i;
if ( assem_instr != 0) {
free( assem_instr);
assem_instr = 0;
}
for ( i = 0; i < n_ops; i++) {
free( op_info[i].name);
op_info[i].name = 0;
if ( op_info[i].type != 0) {
free( op_info[i].type);
op_info[i].type = 0;
}
}
n_ops = 0;
}
operand_clean()
/* Naam van de assembler-instr bewaren! */
{
int i;
for ( i = 0; i < n_ops; i++) {
free( op_info[i].name);
op_info[i].name = 0;
if ( op_info[i].type != 0) {
free( op_info[i].type);
op_info[i].type = 0;
}
}
n_ops = 0;
}
out( fmt, argv)
char *fmt;
int argv;
{
doprnt( outfile, fmt, &argv);
}
error( fmt, argv)
char *fmt;
int argv;
{
fprint( STDERR, "!! ERROR : ");
doprnt( STDERR, fmt, &argv);
fprint( STDERR, " !!\n");
}
inc_ops()
{
n_ops++;
}
/**********************************/
char *mnemonic[ MAX_MNEMONICS];
int n_mnems = 0;
save_mnem( mnem)
char *mnem;
{
if ( n_mnems == MAX_MNEMONICS)
error( "too many assembler instructions!! MAX_MNEMONICS = %d",
MAX_MNEMONICS);
else
mnemonic[ n_mnems++] = Salloc( mnem, strlen( mnem) + 1);
}
end_table()
/* array's wegschrijven !! */
{
int i;
quicksort( 0, n_mnems - 1);
out( "char *mnemonic[] = {\n");
for ( i = 0; i < n_mnems - 1; i++)
out( "\t\"%s\",\n", mnemonic[i]);
out( "\t\"%s\"};\n\n", mnemonic[ n_mnems-1]);
out( "int (*instruction[])() = {\n");
for ( i = 0; i < n_mnems - 1; i++)
out( "\t%s_instr,\n", mnemonic[i]);
out( "\t%s_instr};\n\n", mnemonic[ n_mnems-1]);
out( "int n_mnems = %d;\n", n_mnems);
}
quicksort( lower, upper)
int lower, upper;
/* Deze routine sorteert het array 'mnemonic' mbv. het algorithme quick_sort.
* ( zie diktaat "inleiding programmeren" voor een PASCAL versie.)
*/
{
char *key, *tmp;
int index1, index2;
if ( lower >= upper)
return;
key = mnemonic[lower];
index1 = lower;
index2 = upper+1;
while ( index1 < index2) {
do
index1++;
while (index1 <= upper && strcmp( mnemonic[index1], key) < 0 );
do
index2--;
while ( strcmp( mnemonic[index2], key) > 0);
if ( index1 < index2) {
tmp = mnemonic[index2];
mnemonic[index2] = mnemonic[index1];
mnemonic[index1] = tmp;
}
}
mnemonic[lower] = mnemonic[index2];
mnemonic[index2] = key;
quicksort( lower, index2-1);
quicksort( index2+1, upper);
}

157
util/ceg/as_parser/pars.g Normal file
View File

@@ -0,0 +1,157 @@
{
#include "decl.h"
extern int yylineno, yyleng, yymorfg;
extern char yytext[];
}
%token IDENTIFIER, CALL, CONDITION, IF, ELSIF, ELSE, FI, ARROW, MORE;
%start table, table;
%lexical lex_analyzer ;
table : { init_table();}
instruction* { end_table();}
;
instruction : { clean();}
first_row
[ { operand_clean();}
extra_row
]* { pr_warning(); out( "}\n\n");}
;
first_row : mnemonic { save_instr( yytext, yyleng);}
[ decl_list]?
ARROW { pr_header(); pr_restriction();}
action_list
;
extra_row : MORE
[ decl_list]?
ARROW { out( "else "); pr_restriction();}
action_list
;
mnemonic : IDENTIFIER
;
decl_list : { clear_restriction();}
declaration
[ ',' declaration] *7
;
declaration : IDENTIFIER { save_name( yytext, yyleng);}
[ ':'
IDENTIFIER { save_type( yytext, yyleng);}
]? { inc_ops();}
;
action_list : { out( "{\n");}
[ action [ ';' action]* ]? '.' { out( "}\n");}
;
action : if_statement
| call
| subroutine
;
subroutine : IDENTIFIER { yymorfg=1;}
CONDITION { pr_subroutine( yytext);}
;
call : '@'
IDENTIFIER { yymorfg=1;}
CONDITION { pr_call( yytext);}
;
if_statement : IF
CONDITION { pr_question( yytext);}
action_list { pr_end();}
[ ELSIF { pr_els();}
CONDITION { pr_question( yytext);}
action_list { pr_end();}
]*
[ ELSE { pr_else();}
action_list { pr_end();}
]?
FI
;
{
static int saved = 0, token;
LLmessage( inserted_token)
int inserted_token;
{
if ( inserted_token == 0) {
fprint( STDERR, "Sytax error in line %d, ", yylineno);
print_token( LLsymb);
fprint( STDERR, " will be deleted!!\n");
}
else if ( inserted_token < 0) {
fprint( STDERR, "Stack overflow in line %d, fatal error!\n",
yylineno);
exit( 1);
}
else {
fprint( STDERR, "Sytax error in line %d, ", yylineno);
print_token( inserted_token);
fprint( STDERR, " will be inserted!!\n");
token = LLsymb;
saved = 1;
}
}
print_token( token)
int token;
{
switch ( token) {
case IDENTIFIER : fprint( STDERR, "IDENTIFIER %s", yytext);
break;
case CALL : fprint( STDERR, "CALL %s", yytext);
break;
case CONDITION: fprint( STDERR, "CONDITION %s", yytext);
break;
case IF : fprint( STDERR, "@if ");
break;
case ELSIF : fprint( STDERR, "@elsif ");
break;
case ELSE : fprint( STDERR, "@else ");
break;
case FI : fprint( STDERR, "@fi ");
break;
case ARROW : fprint( STDERR, "==> ");
break;
case MORE : fprint( STDERR, "... ");
break;
default : fprint( STDERR, "%c ", token);
break;
}
}
int lex_analyzer()
{
int tok;
if ( saved) {
saved = 0;
return( token);
}
else {
tok = yylex();
yytext[yyleng] = '\0'; /* strings moeten op een '\0' eindigen */
return( tok);
}
}
main()
{
table();
return( 0);
}
}

View File

@@ -0,0 +1,52 @@
ws ([ \t\n]*)
arrow ("==>")
letter ([a-zA-Z_])
digit ([0-9])
identifier ({letter}({letter}|{digit})*)
%start COM CAL CON
%{
#include "Lpars.h"
#include "decl.h"
int special, n_haakjes;
%}
%%
"/*" BEGIN COM;
<COM>[^\n\*]*"*"+"/" BEGIN 0;
<COM>[^\n^\*]*"*"+ ;
<COM>[^\n\*]*"\n" ;
";" return( ';');
"." return( '.');
"," return( ',');
":" return( ':');
"@" return( '@');
"@if"{ws} return( IF);
"@elsif"{ws} return( ELSIF);
"@else"{ws} return( ELSE);
"@fi"{ws} return( FI);
"..." return( MORE);
{arrow} return( ARROW);
{identifier} return( IDENTIFIER);
"(" { BEGIN CON; n_haakjes = 1; yymore();}
<CON>[^()]*"(" { n_haakjes++; yymore();}
<CON>[^()]*")" { if ( n_haakjes == 1) {
BEGIN 0;
return( CONDITION);
}
else {
n_haakjes--;
yymore();
}
}
{ws} ;