x86.brg: (MB_OPT_LEVEL): define optimisation level macro
[mono.git] / mono / monoburg / monoburg.y
1 %{
2 /*
3  * monoburg.y: yacc input grammer
4  *
5  * Author:
6  *   Dietmar Maurer (dietmar@ximian.com)
7  *
8  * (C) 2001 Ximian, Inc.
9  */
10
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <ctype.h>
15 #include <assert.h>
16 #include <stdarg.h>
17
18 #include "monoburg.h"
19   
20 static int yylineno = 0;
21 static int yylinepos = 0;
22
23 %}
24
25 %union {
26   char *text;
27   int   ivalue;
28   Tree  *tree;
29 }
30
31 %token <text> IDENT
32 %token <text> CODE
33 %token <text> STRING
34 %token  START
35 %token  COST
36 %token  TERM
37 %token <ivalue> INTEGER
38
39 %type   <tree>          tree
40 %type   <text>          optcost
41 %type   <text>          optcfunc
42 %type   <text>          optcode
43
44 %%
45
46 decls   : /* empty */ 
47         | START IDENT { start_nonterm ($2); } decls
48         | TERM  tlist decls
49         | IDENT ':' tree optcost optcode optcfunc { create_rule ($1, $3, $5, $4, $6); } decls 
50         ;
51
52 optcode : /* empty */ { $$ = NULL }
53         | CODE 
54         ;
55
56 tlist   : /* empty */
57         | tlist IDENT { create_term ($2, -1);}
58         | tlist IDENT '=' INTEGER { create_term ($2, $4); }
59         ;
60
61 tree    : IDENT { $$ = create_tree ($1, NULL, NULL); }
62         | IDENT '(' tree ')' { $$ = create_tree ($1, $3, NULL); }
63         | IDENT '(' tree ',' tree ')' { $$ = create_tree ($1, $3, $5); }
64         ;
65
66 optcost : /* empty */ {$$ = NULL; }
67         | STRING
68         | INTEGER { $$ = g_strdup_printf ("%d", $1); }
69         ;
70
71 optcfunc : /*empty */ { $$ = NULL; }
72          | COST CODE { $$ = $2; }
73          ;
74 %%
75
76 static char *
77 strndup (const char *s, int n)
78 {
79   char *ns = malloc (n + 1);
80   strncpy (ns, s, n);
81   ns [n + 1] = '\0';
82   return ns;
83 }
84
85 static char input[2048];
86 static char *next = input;
87
88 void 
89 yyerror (char *fmt, ...)
90 {
91   va_list ap;
92
93   va_start(ap, fmt);
94
95   fprintf (stderr, "line %d(%d): ", yylineno, yylinepos);
96   vfprintf (stderr, fmt, ap);
97   fprintf(stderr, "\n");
98
99   va_end (ap);
100
101   exit (-1);
102 }
103
104 static char
105 nextchar ()
106 {
107   static int state = 0;
108   int next_state ;
109   gboolean ll;
110
111     if (!*next) {
112       next = input;
113       *next = 0;
114       do {
115         if (!fgets (input, sizeof (input), inputfd))
116           return 0;
117
118         ll = (input [0] == '%' && input [1] == '%');
119         next_state = state;
120
121         switch (state) {
122         case 0:
123           if (ll) {
124             next_state = 1;
125           } else 
126             fputs (input, outputfd);
127           break;
128         case 1:
129           if (ll) {
130             next_state = 2;
131             *next = 0;
132           }
133           break;
134         default:
135           return 0;
136         }
137         ll = state != 1 || input[0] == '#';
138         state = next_state;
139         yylineno++;
140       } while (next_state == 2 || ll);
141     } 
142
143     return *next++;
144 }
145
146 void
147 yyparsetail (void)
148 {
149   fputs (input, outputfd);
150   while (fgets (input, sizeof (input), inputfd))
151     fputs (input, outputfd);
152 }
153
154 int 
155 yylex (void) 
156 {
157   char c;
158
159   do {
160
161     if (!(c = nextchar ()))
162       return 0;
163
164     yylinepos = next - input + 1;
165
166     if (isspace (c))
167       continue;
168
169     if (c == '%') {
170       if (!strncmp (next, "start", 5) && isspace (next[5])) {
171         next += 5;
172         return START;
173       }
174
175       if (!strncmp (next, "term", 4) && isspace (next[4])) {
176         next += 4;
177         return TERM;
178       }
179       return c;
180     }
181
182     if (isdigit (c)) {
183             int num = 0;
184
185             do {
186                     num = 10*num + (c - '0');
187             } while ((c = isdigit (*next++)));
188
189             yylval.ivalue = num;
190             return INTEGER;
191     }
192
193     if (isalpha (c)) {
194       char *n = next;
195       int l;
196
197       if (!strncmp (next - 1, "cost", 4) && isspace (next[3])) {
198         next += 4;
199         return COST;
200       }
201
202       while (isalpha (*n) || isdigit (*n) || (*n == '_')) 
203               n++;
204
205       l = n - next + 1;
206       yylval.text = strndup (next - 1, l);
207       next += l - 1;
208
209       return IDENT;
210     }
211     
212     if (c == '"') {
213       int i = 0;
214       static char buf [100000];
215  
216       while ((c = *next++) != '"' && c)
217         buf [i++] = c;
218       
219       buf [i] = '\0';
220       yylval.text = strdup (buf);
221
222       return STRING;
223     }
224
225     if (c == '{') {
226       int i = 0, d = 1;
227       static char buf [100000];
228  
229       while (d && (c = nextchar ())) {
230         buf [i++] = c;
231         assert (i < sizeof (buf));
232
233         switch (c) {
234         case '{': d++; break;
235         case '}': d--; break;
236         default:
237                 break;
238         }
239       }
240       buf [--i] = '\0';
241       yylval.text = strdup (buf);
242
243       return CODE;
244     }
245     
246     return c;
247   
248   } while (1);
249 }
250