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