Pristine Ack-5.5
[Ack-5.5.git] / lang / occam / comp / lex.l
1 %{
2 /* $Id: lex.l,v 1.8 1994/06/24 12:27:04 ceriel Exp $ */
3 /*
4  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
5  * See the copyright notice in the ACK home directory, in the file "Copyright".
6  */
7 # include <ctype.h>
8 # include "token.h"
9 # include "Lpars.h"
10
11 # define TAB    8       /* Size of a acsii tab (\t) in spaces */
12 # if (TAB&(TAB-1))!=0
13 # define TABSTOP(ind)   ((ind)+TAB-(ind)%TAB)
14 # else
15 # define TABSTOP(ind)   (((ind)+TAB)&(~(TAB-1)))
16 # endif
17
18 char *Malloc(), *strcpy();
19
20 struct token token;
21 int ind=0;              /* Indentation level of current line */
22 static int tab=0;       /* First indentation found */
23
24 int included=0;         /* Is current file included? */
25 int lineno = 1;
26 %}
27
28 %%
29 '((\*[^\n])|([^'\n*]))*'        {
30         if ((token.t_lval=char_constant(yytext+1))== -1L) 
31                 report("%s not a character constant", yytext);
32
33         return CHAR_CONST;
34 }
35 '[^'\n]*'?                      {
36         report("missing '.");
37         token.t_lval= -1L;
38
39         return CHAR_CONST;
40 }
41 \"((\*[^\n])|([^"\n*]))*\"      {
42         char *string();
43
44         token.t_sval=string(yytext);
45
46         return STRING;
47 }
48 \"[^"\n]*\"?                    {
49         report("missing \".");
50         token.t_sval="";
51
52         return STRING;
53 }
54 #[ \t]*"line"?[ \t]*[0-9]+[ \t]*\"[^"\n]*\"     {
55         set_line_file(yytext);
56         tab=0;
57 }
58 #[A-Fa-f0-9]+                   {
59         long hex_number();
60
61         token.t_lval=hex_number(yytext+1);
62
63         return NUMBER;
64 }
65 [0-9]+                          {
66         long number();
67
68         token.t_lval=number(yytext);
69
70         return NUMBER;
71 }
72 [A-Za-z][A-Za-z0-9.]*           {
73         register key;
74
75         if ((key=keyword(yytext))==IDENTIFIER)
76                 token.t_sval=strcpy(Malloc(yyleng+1), yytext);
77         
78         return key;
79 }
80 \n[ \f\t]*/"--"                 {/* Line with only a comment, don't set tab */
81                                  lineno++;
82                                 }
83
84 \n[ \f\t]*                      {
85
86         lineno++;
87         ind=indentation(yytext+1);
88         if (tab==0)
89                 tab=ind;
90         else
91         if (ind%tab!=0)
92                 warning("indentation not on a %d space boundary", tab);
93 }
94 [ \f\t]                         { /* Nothing */ }
95 [-=<>:,;+*/\[\]()?!&]           return yytext[0];
96
97 "\\"                            return BS;
98 ":="                            return AS;
99 "<="                            return LE;
100 ">="                            return GE;
101 "<>"                            return NE;
102 "<<"                            return LS;
103 ">>"                            return RS;
104 "/\\"                           return BA;
105 "\\/"                           return BO;
106 "><"                            return BX;
107
108 "--"[^\n]*                      { /* Comment is skipped */ }
109 .                               {
110         warning((' '<=yytext[0] && yytext[0]<0177) ? "%s'%c')" : "%soctal: %o)",
111                 "bad character seen (", yytext[0]&0377);
112 }
113 %%
114 char *string(s) char *s;
115 {
116         register c;
117         register char *p= s;
118         char *str= s;
119         
120         str++; p++;
121         while (*str != '"') {
122                 if ((c=character(&str)) != -1)
123                         *p++= c;
124                 else
125                         return "";
126         }
127
128         *p=0;
129         *s=p-(s+1);
130         return s;
131 }
132
133 long number(s) register char *s;
134 {
135         static char max_str[]="2147483647";
136         int  maxlen=sizeof max_str-1;
137         long atol();
138         long num;
139
140         while (*s=='0') { /* skip leading nulls */
141                 *s++;
142                 yyleng--;
143         }
144
145         if (*s==0)
146                 num=0L;
147         else {
148                 if ((yyleng>maxlen) || (yyleng==maxlen && strcmp(s, max_str)>0))
149                         warning("integer constant overflow.");
150
151                 num=atol(s);
152         }
153
154         return num;
155 }
156                 
157 long hex_number(s) register char *s;
158 {
159         long number=0L;
160
161         while (*s)
162                 number=(number<<4)+hextoint(*s++);
163
164         return number;
165 }
166
167 int hextoint(c) register c;
168 {
169         register val;
170         
171         if (islower(c))
172                 val=(c-'a')+10;
173         else
174         if (isupper(c))
175                 val=(c-'A')+10;
176         else
177                 val=c-'0';
178         
179         return val;
180 }
181
182 int character(S) register char **S;
183 {
184         register char *s= *S;
185         register c, cc;
186
187         if ((c= *s++)=='*') {
188                 switch (c= *s++) {
189                 case 'c':
190                         cc='\r';
191                         break;
192                 case 'n':
193                         cc='\n';
194                         break;
195                 case 't':
196                         cc='\t';
197                         break;
198                 case 's':
199                         cc=' ';
200                         break;
201                 case '#':
202                         if (isxdigit(c= *s++) && isxdigit(*s)) {
203                                 cc= (hextoint(c)<<4)+hextoint(*s++);
204                                 break;
205                         } else {
206                                 report("two digit hexadecimal const expected.");
207                                 return -1;
208                         }
209                 default:
210                         cc=c;
211                         break;
212                 }
213         } else
214                 cc=c;
215         
216         *S=s;
217         return cc;
218 }
219         
220 int char_constant(s) char *s;
221 {
222         register cc;
223
224         cc=character(&s);
225
226         return (*s=='\'' && cc!= -1) ? cc : -1;
227 }
228
229 int indentation(s) register char *s;
230 {
231         register in=0, c;
232
233         while (c= *s++) {
234                 if (c=='\t')
235                         in=TABSTOP(in);
236                 else
237                 if (c=='\f')
238                         in=0;
239                 else
240                         in++;
241         }
242         
243         return in;
244 }
245
246 int tabulated(oind, ind) register oind, ind;
247 {
248         if (tab>0 && ind>oind+tab)
249                 warning("process' indentation too large (changed to %d tab%s)",
250                         oind/tab+1, oind>=tab ? "s" : "");
251         return ind>oind;
252 }
253
254 int rep_tk=0;
255 struct token rep_token;
256
257 void repeat_token(tk)
258 {
259         rep_tk=tk;
260         rep_token=token;
261 }
262
263 scanner()
264 {
265         register tk;
266
267         if (rep_tk>0) {
268                 tk=rep_tk;;
269                 rep_tk=0;
270                 token=rep_token;
271                 return tk;
272         } else
273                 return yylex();
274 }
275
276 char *tokenname(tk, inst) register tk, inst;
277 {
278         if (tk<0400) {
279                 static char c[7];
280
281                 if (' '<tk && tk<='~')
282                         sprint(c, "'%c'", tk);
283                 else
284                         sprint(c, "'*#%02x'", tk);
285                 return c;
286         } else {
287                 switch (tk) {
288                         char *keyname();
289                         char fake_id[1+sizeof(int)*3+1];
290                         static fake_cnt=0;
291                 default:
292                         return keyname(tk);
293                 case IDENTIFIER:
294                         if (inst) {
295                                 sprint(fake_id, "_%d", ++fake_cnt);
296                                 token.t_sval=strcpy(Malloc(strlen(fake_id)+1),
297                                         fake_id);
298                                 return "IDENTIFIER";
299                         } else
300                                 return token.t_sval;
301                 case NUMBER:
302                 case CHAR_CONST:
303                         token.t_lval=0L;
304                         return "NUMBER";
305                 case STRING:
306                         if (inst) {
307                                 token.t_sval=Malloc(1);
308                                 token.t_sval[0]=0;
309                         } else
310                                 free(token.t_sval);
311                         return "STRING";
312                 case AS:        case LE:        case GE:        case NE:
313                 case LS:        case RS:        case BA:        case BO:
314                 case BX:        case BS:        {
315                         static int op[]= {
316                                 AS, LE, GE, NE, LS, RS, BA, BO, BX, BS
317                         };
318                         static char *opc[]= {
319                                 ":=", "<=", ">=", "<>", "<<", ">>", "/\\",
320                                 "\\/", "><", "\\"
321                         };
322                         register i;
323                         static char qopc[5];
324
325                         for (i=0; op[i]!=tk; i++) ;
326                         sprint(qopc, "'%s'", opc[i]);
327                         return qopc;
328                         }
329                 }
330         }
331 }
332
333 set_line_file(l) register char *l;
334 {
335         register char *file;
336
337         while (*l<'0' || *l>'9') l++;
338
339         lineno=0;
340         while ('0'<=*l && *l<='9')
341                 lineno=lineno*10+(*l++ - '0');
342
343         lineno--;
344
345         while (*l++!='"');
346
347         file=l;
348         while (*l++!='"');
349         *--l=0;
350
351         included=set_file(file);
352 }