217 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			217 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| /* 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.
 | |
|  */
 | |
| 
 | |
| {
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| 
 | |
| #include "decl.h"
 | |
| extern int lineno, yyleng;
 | |
| #ifdef FLEX
 | |
| extern char *yytext;
 | |
| #else
 | |
| extern char yytext[];
 | |
| #endif
 | |
| 
 | |
| }
 | |
| 
 | |
| %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
 | |
| 		;
 | |
| 
 | |
| /* A function call is just an identifier followed by an expression surrounded
 | |
|  * by '(' and ')'. CONDITION is a token that matches this construct;
 | |
|  */
 | |
| 
 | |
| 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);
 | |
| 					}
 | |
| 		;
 | |
| 
 | |
| 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);
 | |
| 					}
 | |
| 		;
 | |
| 
 | |
| 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
 | |
| 		;
 | |
| 
 | |
| {
 | |
| 
 | |
| int nerrors;
 | |
| static int saved = 0, token;
 | |
| 
 | |
| 
 | |
| LLmessage( inserted_token)
 | |
| int inserted_token;
 | |
| {
 | |
| 	nerrors++;
 | |
| 	if ( inserted_token == 0) {
 | |
| 		fprint( STDERR, "Sytax error in line %d, ", lineno);
 | |
| 		print_token( LLsymb);
 | |
| 		fprint( STDERR, "  will be deleted!!\n");
 | |
| 	}
 | |
| 	else if ( inserted_token < 0) {
 | |
| 		fprint( STDERR, "Garbage at end, line %d!!\n",
 | |
| 			 lineno);
 | |
| 	}
 | |
| 	else {
 | |
| 		fprint( STDERR, "Sytax error in line %d, ", lineno);
 | |
| 		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 must end with '\0' */
 | |
| 		return( tok);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| main()
 | |
| {
 | |
| 	table();
 | |
| 	exit(nerrors);
 | |
| }
 | |
| 
 | |
| }
 |