Initial revision
This commit is contained in:
28
util/ceg/as_parser/Makefile
Normal file
28
util/ceg/as_parser/Makefile
Normal 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
|
||||
5
util/ceg/as_parser/as_parser.h
Normal file
5
util/ceg/as_parser/as_parser.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#include <em.h>
|
||||
#include <system.h>
|
||||
|
||||
extern File *outfile;
|
||||
extern arith cur_pos;
|
||||
7
util/ceg/as_parser/const.h
Normal file
7
util/ceg/as_parser/const.h
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
#define Bool int
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define MAX_OPERANDS 4
|
||||
#define MAX_MNEMONICS 100
|
||||
97
util/ceg/as_parser/conversion.c
Normal file
97
util/ceg/as_parser/conversion.c
Normal 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);
|
||||
}
|
||||
3
util/ceg/as_parser/decl.h
Normal file
3
util/ceg/as_parser/decl.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#include <alloc.h>
|
||||
#include <system.h>
|
||||
#include "const.h"
|
||||
2
util/ceg/as_parser/eval/Makefile
Normal file
2
util/ceg/as_parser/eval/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
eval : eval.c states.h
|
||||
cc -o eval eval.c
|
||||
309
util/ceg/as_parser/eval/eval.c
Normal file
309
util/ceg/as_parser/eval/eval.c
Normal 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);
|
||||
}
|
||||
11
util/ceg/as_parser/eval/states.h
Normal file
11
util/ceg/as_parser/eval/states.h
Normal 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
287
util/ceg/as_parser/help.c
Normal 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
157
util/ceg/as_parser/pars.g
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
52
util/ceg/as_parser/table.l
Normal file
52
util/ceg/as_parser/table.l
Normal 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} ;
|
||||
Reference in New Issue
Block a user