Pristine Ack-5.5
[Ack-5.5.git] / util / ceg / as_parser / pars.g
1 /* This file contains the description of the 'as_table' parser.
2  * It transforms every entry into a C-funtion, for example :
3  *
4  *      and dst:REG, src:EADDR  ==>     @text1( 0x23);
5  *                                      mod_RM( dst->reg, src).
6  *
7  *      ... dst:ACCU, src:DATA  ==>     @text1( 0x25);
8  *                                      @text2(
9  *                                      %$(src->expr)).
10  *
11  * Will be transformed into :
12  *
13  *      and_instr( dst, src)
14  *      struct t_operand *dst, *src;
15  *      {
16  *              if (  REG( dst) && EADDR( src)) {
17  *                       cur_pos += 1;
18  *                       fprint( outfile, "text1( 0x23)");
19  *                       fprint( outfile, ";");
20  *                       mod_RM( dst->reg, src);
21  *              }
22  *              else if ( ACCU( dst) && DATA( src)) {
23  *                      cur_pos += 1;
24  *                      fprint( outfile, "text1( 0x25)");
25  *                      fprint( outfile, ";");
26  *                      cur_pos += 2;
27  *                      fprint( outfile, "text2( ");
28  *                      eval( src->expr);
29  *                      fprint( outfile, ")");
30  *                      fprint( outfile, ";");
31  *              }
32  *              else
33  *                      error( "No match for and");
34  *      }
35  * 
36  * At the end of the table a list is generated enumerating all the assembler
37  * mnemonics and their corresponding function names.
38  */
39
40 {
41
42 #include "decl.h"
43 extern int lineno, yyleng;
44 #ifdef FLEX
45 extern char *yytext;
46 #else
47 extern char yytext[];
48 #endif
49
50 }
51
52 %token IDENTIFIER, CALL, CONDITION, IF, ELSIF, ELSE, FI, ARROW, MORE;
53 %start  table, table;
54 %lexical        lex_analyzer ;
55
56
57 table           :                       { init_table();}
58                   instruction*          { end_table();}
59                 ;
60
61 instruction     :                       { clean();}
62                   first_row
63                   [                     { operand_clean();}
64                     extra_row
65                   ]*                    { pr_warning(); out( "}\n\n");}
66                 ;
67
68 first_row       : mnemonic              { save_instr( yytext, yyleng);}
69                   [ decl_list]?
70                   ARROW                 { pr_header(); pr_restriction();}
71                   action_list
72                 ;
73
74 extra_row       : MORE
75                   [ decl_list]?
76                   ARROW                 { out( "else "); pr_restriction();}
77                   action_list
78                 ;
79
80 mnemonic        : IDENTIFIER
81                 ;
82
83 decl_list       :                       { clear_restriction();}
84                   declaration
85                   [ ',' declaration] *7
86                 ;
87
88 declaration     : IDENTIFIER            { save_name( yytext, yyleng);}
89                   [ ':'
90                     IDENTIFIER          { save_type( yytext, yyleng);}
91                   ]?                    { inc_ops();}
92                 ;
93
94 action_list     :                                       { out( "{\n");}
95                   [ action [ ';' action]* ]? '.'        { out( "}\n");}
96                 ;
97
98 action          : if_statement
99                 | call                  
100                 | subroutine
101                 ;
102
103 /* A function call is just an identifier followed by an expression surrounded
104  * by '(' and ')'. CONDITION is a token that matches this construct;
105  */
106
107 subroutine
108   { char *s; }  : IDENTIFIER            { s = Salloc(yytext, yyleng+1); }
109                   CONDITION             { s = Realloc(s, strlen(s)+yyleng+1);
110                                           strcat(s, yytext);
111                                           pr_subroutine( s);
112                                           free(s);
113                                         }
114                 ;
115
116 call
117   { char *s; }  : '@'
118                   IDENTIFIER            { s = Salloc(yytext, yyleng+1); }
119                   CONDITION             { s = Realloc(s, strlen(s)+yyleng+1);
120                                           strcat(s, yytext);
121                                           pr_call( s);
122                                           free(s);
123                                         }
124                 ;
125
126 if_statement    : IF
127                   CONDITION             { pr_question( yytext);}
128                   action_list           { pr_end();}
129                   [ ELSIF               { pr_els();}
130                     CONDITION           { pr_question( yytext);}
131                     action_list         { pr_end();}
132                   ]*
133                   [ ELSE                { pr_else();}
134                     action_list         { pr_end();}
135                   ]?
136                   FI
137                 ;
138
139 {
140
141 int nerrors;
142 static int saved = 0, token;
143
144
145 LLmessage( inserted_token)
146 int inserted_token;
147 {
148         nerrors++;
149         if ( inserted_token == 0) {
150                 fprint( STDERR, "Sytax error in line %d, ", lineno);
151                 print_token( LLsymb);
152                 fprint( STDERR, "  will be deleted!!\n");
153         }
154         else if ( inserted_token < 0) {
155                 fprint( STDERR, "Garbage at end, line %d!!\n",
156                          lineno);
157         }
158         else {
159                 fprint( STDERR, "Sytax error in line %d, ", lineno);
160                 print_token( inserted_token);
161                 fprint( STDERR, "  will be inserted!!\n");
162                 token = LLsymb;
163                 saved = 1;
164         }
165 }
166
167 print_token( token)
168 int token;
169 {
170         switch ( token) {
171           case IDENTIFIER : fprint( STDERR,  "IDENTIFIER %s", yytext);
172                           break;
173           case CALL     : fprint( STDERR,  "CALL  %s", yytext);
174                           break;
175           case CONDITION: fprint( STDERR,  "CONDITION  %s", yytext);
176                           break;
177           case IF       : fprint( STDERR,  "@if ");
178                           break;
179           case ELSIF    : fprint( STDERR,  "@elsif ");
180                           break;
181           case ELSE     : fprint( STDERR,  "@else ");
182                           break;
183           case FI       : fprint( STDERR,  "@fi ");
184                           break;
185           case ARROW    : fprint( STDERR,  "==> ");
186                           break;
187           case MORE     : fprint( STDERR,  "... ");
188                           break;
189           default       : fprint( STDERR, "%c ", token);
190                           break;
191         }
192 }
193
194 int lex_analyzer()
195 {
196         int tok;
197
198         if ( saved) {
199                 saved = 0;
200                 return( token);
201         }
202         else {
203                 tok = yylex();
204                 yytext[yyleng] = '\0'; /* strings must end with '\0' */
205                 return( tok);
206         }
207 }
208
209 main()
210 {
211         table();
212         exit(nerrors);
213 }
214
215 }