1988-01-15 15:57:35 +00:00
|
|
|
/* This file contains the description of the 'as_table' parser.
|
|
|
|
* It transforms every entry into a C-funtion, for example :
|
|
|
|
*
|
|
|
|
* and dst:REG, src:EADDR ==> @text1( 0x23);
|
|
|
|
* mod_RM( dst->reg, src).
|
|
|
|
*
|
|
|
|
* ... dst:ACCU, src:DATA ==> @text1( 0x25);
|
|
|
|
* @text2(
|
|
|
|
* %$(src->expr)).
|
|
|
|
*
|
|
|
|
* Will be transformed into :
|
|
|
|
*
|
|
|
|
* and_instr( dst, src)
|
|
|
|
* struct t_operand *dst, *src;
|
|
|
|
* {
|
|
|
|
* if ( REG( dst) && EADDR( src)) {
|
|
|
|
* cur_pos += 1;
|
|
|
|
* fprint( outfile, "text1( 0x23)");
|
|
|
|
* fprint( outfile, ";");
|
|
|
|
* mod_RM( dst->reg, src);
|
|
|
|
* }
|
|
|
|
* else if ( ACCU( dst) && DATA( src)) {
|
|
|
|
* cur_pos += 1;
|
|
|
|
* fprint( outfile, "text1( 0x25)");
|
|
|
|
* fprint( outfile, ";");
|
|
|
|
* cur_pos += 2;
|
|
|
|
* fprint( outfile, "text2( ");
|
|
|
|
* eval( src->expr);
|
|
|
|
* fprint( outfile, ")");
|
|
|
|
* fprint( outfile, ";");
|
|
|
|
* }
|
|
|
|
* else
|
|
|
|
* error( "No match for and");
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* At the end of the table a list is generated enumerating all the assembler
|
|
|
|
* mnemonics and their corresponding function names.
|
|
|
|
*/
|
|
|
|
|
1987-11-20 11:12:07 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
#include "decl.h"
|
1991-01-11 14:35:14 +00:00
|
|
|
extern int lineno, yyleng;
|
|
|
|
extern char *yytext;
|
1987-11-20 11:12:07 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
%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
|
|
|
|
;
|
|
|
|
|
1988-01-15 15:57:35 +00:00
|
|
|
/* A function call is just an identifier followed by an expression surrounded
|
|
|
|
* by '(' and ')'. CONDITION is a token that matches this construct;
|
|
|
|
*/
|
|
|
|
|
1991-01-11 14:35:14 +00:00
|
|
|
subroutine
|
|
|
|
{ char *s; } : IDENTIFIER { s = Salloc(yytext, yyleng+1); }
|
|
|
|
CONDITION { s = Realloc(s, strlen(s)+yyleng+1);
|
|
|
|
strcat(s, yytext);
|
|
|
|
pr_subroutine( s);
|
|
|
|
free(s);
|
|
|
|
}
|
1987-11-20 11:12:07 +00:00
|
|
|
;
|
|
|
|
|
1991-01-11 14:35:14 +00:00
|
|
|
call
|
|
|
|
{ char *s; } : '@'
|
|
|
|
IDENTIFIER { s = Salloc(yytext, yyleng+1); }
|
|
|
|
CONDITION { s = Realloc(s, strlen(s)+yyleng+1);
|
|
|
|
strcat(s, yytext);
|
|
|
|
pr_call( s);
|
|
|
|
free(s);
|
|
|
|
}
|
1987-11-20 11:12:07 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
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
|
|
|
|
;
|
|
|
|
|
|
|
|
{
|
|
|
|
|
1988-09-09 11:36:57 +00:00
|
|
|
int nerrors;
|
1987-11-20 11:12:07 +00:00
|
|
|
static int saved = 0, token;
|
|
|
|
|
|
|
|
|
|
|
|
LLmessage( inserted_token)
|
|
|
|
int inserted_token;
|
|
|
|
{
|
1988-09-09 11:36:57 +00:00
|
|
|
nerrors++;
|
1987-11-20 11:12:07 +00:00
|
|
|
if ( inserted_token == 0) {
|
1991-01-11 14:35:14 +00:00
|
|
|
fprint( STDERR, "Sytax error in line %d, ", lineno);
|
1987-11-20 11:12:07 +00:00
|
|
|
print_token( LLsymb);
|
|
|
|
fprint( STDERR, " will be deleted!!\n");
|
|
|
|
}
|
|
|
|
else if ( inserted_token < 0) {
|
1988-09-09 11:36:57 +00:00
|
|
|
fprint( STDERR, "Garbage at end, line %d!!\n",
|
1991-01-11 14:35:14 +00:00
|
|
|
lineno);
|
1987-11-20 11:12:07 +00:00
|
|
|
}
|
|
|
|
else {
|
1991-01-11 14:35:14 +00:00
|
|
|
fprint( STDERR, "Sytax error in line %d, ", lineno);
|
1987-11-20 11:12:07 +00:00
|
|
|
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();
|
1989-01-26 14:47:03 +00:00
|
|
|
yytext[yyleng] = '\0'; /* strings must end with '\0' */
|
1987-11-20 11:12:07 +00:00
|
|
|
return( tok);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
main()
|
|
|
|
{
|
|
|
|
table();
|
1988-09-09 11:36:57 +00:00
|
|
|
exit(nerrors);
|
1987-11-20 11:12:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|