~halega/+junk/sharpdevelop

« back to all changes in this revision

Viewing changes to src/Tools/SharpCoco/src/Scanner.cs

  • Committer: sk
  • Date: 2011-09-10 05:17:57 UTC
  • Revision ID: halega@halega.com-20110910051757-qfouz1llya9m6boy
4.1.0.7915 Release Candidate 1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
using System;
 
2
 
 
3
using System.IO;
 
4
 
 
5
using System.Collections;
 
6
 
 
7
using System.Text;
 
8
 
 
9
 
 
10
 
 
11
namespace at.jku.ssw.Coco {
 
12
 
 
13
 
 
14
 
 
15
public class Token {
 
16
 
 
17
        public int kind;    // token kind
 
18
 
 
19
        public int pos;     // token position in the source text (starting at 0)
 
20
 
 
21
        public int col;     // token column (starting at 0)
 
22
 
 
23
        public int line;    // token line (starting at 1)
 
24
 
 
25
        public string val;  // token value
 
26
 
 
27
        public Token next;  // AW 2003-03-07 Tokens are kept in linked list
 
28
 
 
29
        
 
30
 
 
31
        public Token () { }
 
32
 
 
33
        public Token (int kind) { this.kind = kind; }
 
34
 
 
35
}
 
36
 
 
37
 
 
38
 
 
39
public class Buffer {
 
40
 
 
41
        public const int eof = '\uffff';
 
42
        
 
43
        static byte[] buf;
 
44
        static int bufLen;
 
45
        static int pos;
 
46
        public static string fileName;
 
47
        
 
48
        public static int CountLines(int offset)
 
49
        {
 
50
                int line = 0;
 
51
                for (int i = 0; i <= offset; ++i) {
 
52
                        if (buf[i] == '\n') {
 
53
                                ++line;
 
54
                        }
 
55
                }
 
56
                return line;
 
57
        }
 
58
        
 
59
        public static void Fill (string fileName) {
 
60
                Buffer.fileName = fileName;
 
61
                FileStream s = null;
 
62
                try {
 
63
                        s = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
 
64
                        bufLen = (int) s.Length;
 
65
                        buf = new byte[bufLen];
 
66
                        s.Read(buf, 0, bufLen); 
 
67
                        pos = 0;
 
68
 
 
69
                } catch (IOException) {
 
70
 
 
71
                        Console.WriteLine("--- Cannot open file {0}", fileName);
 
72
 
 
73
                        System.Environment.Exit(0);
 
74
 
 
75
                } finally {
 
76
 
 
77
                        if (s != null) s.Close();
 
78
 
 
79
                }
 
80
 
 
81
        }
 
82
 
 
83
        
 
84
 
 
85
        public static int Read () {
 
86
 
 
87
                if (pos < bufLen) return buf[pos++];
 
88
 
 
89
                else return 0;
 
90
 
 
91
        }
 
92
 
 
93
 
 
94
 
 
95
        public static int Peek () {
 
96
 
 
97
                if (pos < bufLen) return buf[pos];
 
98
 
 
99
                else return 0;
 
100
 
 
101
        }
 
102
 
 
103
        
 
104
 
 
105
        /* AW 2003-03-10 moved this from ParserGen.cs */
 
106
 
 
107
        public static string GetString (int beg, int end) {
 
108
 
 
109
                StringBuilder s = new StringBuilder(64);
 
110
 
 
111
                int oldPos = Buffer.Pos;
 
112
 
 
113
                Buffer.Pos = beg;
 
114
 
 
115
                while (beg < end) { s.Append((char)Buffer.Read()); beg++; }
 
116
 
 
117
                Buffer.Pos = oldPos;
 
118
 
 
119
                return s.ToString();
 
120
 
 
121
        }
 
122
 
 
123
 
 
124
 
 
125
        public static int Pos {
 
126
 
 
127
                get { return pos; }
 
128
 
 
129
                set {
 
130
 
 
131
                        if (value < 0) pos = 0; 
 
132
 
 
133
                        else if (value >= bufLen) pos = bufLen; 
 
134
 
 
135
                        else pos = value;
 
136
 
 
137
                }
 
138
 
 
139
        }
 
140
 
 
141
}
 
142
 
 
143
 
 
144
 
 
145
public class Scanner {
 
146
 
 
147
        const char EOF = '\0';
 
148
 
 
149
        const char EOL = '\n';
 
150
 
 
151
        const int maxT = 42;
 
152
 
 
153
 
 
154
 
 
155
        
 
156
 
 
157
        const int noSym = 42;
 
158
 
 
159
        static short[] start = {
 
160
 
 
161
         32,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
162
 
 
163
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
164
 
 
165
          0, 27, 11,  0, 10,  0,  0,  5, 21, 22,  0, 15,  0, 16, 14,  0,
 
166
 
 
167
          2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0, 31, 18, 13, 19,  0,
 
168
 
 
169
          0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 
170
 
 
171
          1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 23,  0, 24,  0,  0,
 
172
 
 
173
          0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 
174
 
 
175
          1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 25, 20, 26,  0,  0,
 
176
 
 
177
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
178
 
 
179
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
180
 
 
181
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
182
 
 
183
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
184
 
 
185
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
186
 
 
187
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
188
 
 
189
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
190
 
 
191
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
192
 
 
193
          0};
 
194
 
 
195
 
 
196
 
 
197
 
 
198
 
 
199
        static Token t;          // current token
 
200
 
 
201
        static char ch;          // current input character
 
202
 
 
203
        static int pos;          // column number of current character
 
204
 
 
205
        static int line;         // line number of current character
 
206
 
 
207
        static int lineStart;    // start position of current line
 
208
 
 
209
        static int oldEols;    // EOLs that appeared in a comment;
 
210
 
 
211
        static BitArray ignore;  // set of characters to be ignored by the scanner
 
212
 
 
213
 
 
214
 
 
215
        /* ML ----- begin */
 
216
 
 
217
        static Token tokens;  // the complete input token stream
 
218
 
 
219
        static Token pt;      // current peek token
 
220
 
 
221
        
 
222
 
 
223
        static int peekCount = 0;
 
224
 
 
225
        
 
226
 
 
227
        public static int PeekCount { get { return peekCount; } }
 
228
 
 
229
 
 
230
 
 
231
        public static void Init (String fileName) {
 
232
 
 
233
                Buffer.Fill(fileName);
 
234
 
 
235
                pos = -1; line = 1; lineStart = 0;
 
236
 
 
237
                oldEols = 0;
 
238
 
 
239
                NextCh();
 
240
 
 
241
                ignore = new BitArray(256);
 
242
 
 
243
                ignore[9] = true; ignore[10] = true; ignore[13] = true; ignore[32] = true; 
 
244
 
 
245
                
 
246
 
 
247
 
 
248
 
 
249
                /* AW 2003-03-07 fill token list */
 
250
 
 
251
                tokens = new Token();  // first token is a dummy
 
252
 
 
253
                Token node = tokens;
 
254
 
 
255
                do {
 
256
 
 
257
                        node.next = NextToken();
 
258
 
 
259
                        node = node.next;
 
260
 
 
261
                } while (node.kind != 0);       /* AW: 0 => EOF */
 
262
 
 
263
                t = pt = tokens;
 
264
 
 
265
        }
 
266
 
 
267
        
 
268
 
 
269
        static void NextCh() {
 
270
 
 
271
                if (oldEols > 0) { ch = EOL; oldEols--; } 
 
272
 
 
273
                else {
 
274
 
 
275
                        ch = (char)Buffer.Read(); pos++;
 
276
 
 
277
                        // replace isolated '\r' by '\n' in order to make
 
278
 
 
279
                        // eol handling uniform across Windows, Unix and Mac
 
280
 
 
281
                        if (ch == '\r' && Buffer.Peek() != '\n') ch = EOL;
 
282
 
 
283
                        else if (ch > '\u007f') ch = '?';
 
284
 
 
285
                        if (ch == EOL) { line++; lineStart = pos + 1; }
 
286
 
 
287
                }
 
288
 
 
289
        }
 
290
 
 
291
        
 
292
 
 
293
 
 
294
        static bool Comment0() {
 
295
 
 
296
                int level = 1, line0 = line, lineStart0 = lineStart;
 
297
 
 
298
                NextCh();
 
299
 
 
300
                if (ch == '*') {
 
301
 
 
302
                        NextCh();
 
303
 
 
304
                        for(;;) {
 
305
 
 
306
                                if (ch == '*') {
 
307
 
 
308
                                        NextCh();
 
309
 
 
310
                                        if (ch == '/') {
 
311
 
 
312
                                                level--;
 
313
 
 
314
                                                if (level == 0) { oldEols = line - line0; NextCh(); return true; }
 
315
 
 
316
                                                NextCh();
 
317
 
 
318
                                        }
 
319
 
 
320
                                } else if (ch == '/') {
 
321
 
 
322
                                        NextCh();
 
323
 
 
324
                                        if (ch == '*') {
 
325
 
 
326
                                                level++; NextCh();
 
327
 
 
328
                                        }
 
329
 
 
330
                                } else if (ch == EOF) return false;
 
331
 
 
332
                                else NextCh();
 
333
 
 
334
                        }
 
335
 
 
336
                } else {
 
337
 
 
338
                        if (ch==EOL) {line--; lineStart = lineStart0;}
 
339
 
 
340
                        pos = pos - 2; Buffer.Pos = pos+1; NextCh();
 
341
 
 
342
                }
 
343
 
 
344
                return false;
 
345
 
 
346
        }
 
347
 
 
348
 
 
349
 
 
350
        
 
351
 
 
352
        static void CheckLiteral() {
 
353
 
 
354
                switch (t.val) {
 
355
 
 
356
                        case "COMPILER": t.kind = 6; break;
 
357
 
 
358
                        case "PRODUCTIONS": t.kind = 7; break;
 
359
 
 
360
                        case "END": t.kind = 10; break;
 
361
 
 
362
                        case "CHARACTERS": t.kind = 11; break;
 
363
 
 
364
                        case "TOKENS": t.kind = 12; break;
 
365
 
 
366
                        case "PRAGMAS": t.kind = 13; break;
 
367
 
 
368
                        case "COMMENTS": t.kind = 14; break;
 
369
 
 
370
                        case "FROM": t.kind = 15; break;
 
371
 
 
372
                        case "TO": t.kind = 16; break;
 
373
 
 
374
                        case "NESTED": t.kind = 17; break;
 
375
 
 
376
                        case "IGNORE": t.kind = 18; break;
 
377
 
 
378
                        case "TOKENNAMES": t.kind = 19; break;
 
379
 
 
380
                        case "ANY": t.kind = 23; break;
 
381
 
 
382
                        case "WEAK": t.kind = 27; break;
 
383
 
 
384
                        case "SYNC": t.kind = 34; break;
 
385
 
 
386
                        case "IF": t.kind = 35; break;
 
387
 
 
388
                        case "CONTEXT": t.kind = 37; break;
 
389
 
 
390
                        case "using": t.kind = 40; break;
 
391
 
 
392
                        default: break;
 
393
 
 
394
 
 
395
 
 
396
                }
 
397
 
 
398
        }
 
399
 
 
400
 
 
401
 
 
402
        /* AW Scan() renamed to NextToken() */
 
403
 
 
404
        static Token NextToken() {
 
405
 
 
406
                while (ignore[ch]) NextCh();
 
407
 
 
408
                if (ch == '/' && Comment0()) return NextToken();
 
409
 
 
410
                t = new Token();
 
411
 
 
412
                t.pos = pos; t.col = pos - lineStart + 1; t.line = line; 
 
413
 
 
414
                int state = start[ch];
 
415
 
 
416
                StringBuilder buf = new StringBuilder(16);
 
417
 
 
418
                buf.Append(ch); NextCh();
 
419
 
 
420
                
 
421
 
 
422
                switch (state) {
 
423
 
 
424
                        case 0: { t.kind = noSym; goto done; }  // NextCh already done
 
425
 
 
426
                        case 1:
 
427
 
 
428
                                if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 1;}
 
429
 
 
430
                                else {t.kind = 1; t.val = buf.ToString(); CheckLiteral(); return t;}
 
431
 
 
432
                        case 2:
 
433
 
 
434
                                if ((ch >= '0' && ch <= '9')) {buf.Append(ch); NextCh(); goto case 2;}
 
435
 
 
436
                                else {t.kind = 2; goto done;}
 
437
 
 
438
                        case 3:
 
439
 
 
440
                                {t.kind = 3; goto done;}
 
441
 
 
442
                        case 4:
 
443
 
 
444
                                {t.kind = 4; goto done;}
 
445
 
 
446
                        case 5:
 
447
 
 
448
                                if ((ch >= 1 && ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '&' || ch >= '(' && ch <= '[' || ch >= ']')) {buf.Append(ch); NextCh(); goto case 6;}
 
449
 
 
450
                                else if (ch == 92) {buf.Append(ch); NextCh(); goto case 7;}
 
451
 
 
452
                                else {t.kind = noSym; goto done;}
 
453
 
 
454
                        case 6:
 
455
 
 
456
                                if (ch == 39) {buf.Append(ch); NextCh(); goto case 9;}
 
457
 
 
458
                                else {t.kind = noSym; goto done;}
 
459
 
 
460
                        case 7:
 
461
 
 
462
                                if ((ch >= ' ' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 8;}
 
463
 
 
464
                                else {t.kind = noSym; goto done;}
 
465
 
 
466
                        case 8:
 
467
 
 
468
                                if ((ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'f')) {buf.Append(ch); NextCh(); goto case 8;}
 
469
 
 
470
                                else if (ch == 39) {buf.Append(ch); NextCh(); goto case 9;}
 
471
 
 
472
                                else {t.kind = noSym; goto done;}
 
473
 
 
474
                        case 9:
 
475
 
 
476
                                {t.kind = 5; goto done;}
 
477
 
 
478
                        case 10:
 
479
 
 
480
                                if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 10;}
 
481
 
 
482
                                else {t.kind = 43; goto done;}
 
483
 
 
484
                        case 11:
 
485
 
 
486
                                if ((ch >= 1 && ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']')) {buf.Append(ch); NextCh(); goto case 11;}
 
487
 
 
488
                                else if ((ch == 10 || ch == 13)) {buf.Append(ch); NextCh(); goto case 4;}
 
489
 
 
490
                                else if (ch == '"') {buf.Append(ch); NextCh(); goto case 3;}
 
491
 
 
492
                                else if (ch == 92) {buf.Append(ch); NextCh(); goto case 12;}
 
493
 
 
494
                                else {t.kind = noSym; goto done;}
 
495
 
 
496
                        case 12:
 
497
 
 
498
                                if ((ch >= ' ' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 11;}
 
499
 
 
500
                                else {t.kind = noSym; goto done;}
 
501
 
 
502
                        case 13:
 
503
 
 
504
                                {t.kind = 8; goto done;}
 
505
 
 
506
                        case 14:
 
507
 
 
508
                                if (ch == '.') {buf.Append(ch); NextCh(); goto case 17;}
 
509
 
 
510
                                else if (ch == ')') {buf.Append(ch); NextCh(); goto case 30;}
 
511
 
 
512
                                else {t.kind = 9; goto done;}
 
513
 
 
514
                        case 15:
 
515
 
 
516
                                {t.kind = 20; goto done;}
 
517
 
 
518
                        case 16:
 
519
 
 
520
                                {t.kind = 21; goto done;}
 
521
 
 
522
                        case 17:
 
523
 
 
524
                                {t.kind = 22; goto done;}
 
525
 
 
526
                        case 18:
 
527
 
 
528
                                {t.kind = 24; goto done;}
 
529
 
 
530
                        case 19:
 
531
 
 
532
                                {t.kind = 25; goto done;}
 
533
 
 
534
                        case 20:
 
535
 
 
536
                                {t.kind = 26; goto done;}
 
537
 
 
538
                        case 21:
 
539
 
 
540
                                if (ch == '.') {buf.Append(ch); NextCh(); goto case 29;}
 
541
 
 
542
                                else {t.kind = 28; goto done;}
 
543
 
 
544
                        case 22:
 
545
 
 
546
                                {t.kind = 29; goto done;}
 
547
 
 
548
                        case 23:
 
549
 
 
550
                                {t.kind = 30; goto done;}
 
551
 
 
552
                        case 24:
 
553
 
 
554
                                {t.kind = 31; goto done;}
 
555
 
 
556
                        case 25:
 
557
 
 
558
                                {t.kind = 32; goto done;}
 
559
 
 
560
                        case 26:
 
561
 
 
562
                                {t.kind = 33; goto done;}
 
563
 
 
564
                        case 27:
 
565
 
 
566
                                if (ch == '=') {buf.Append(ch); NextCh(); goto case 28;}
 
567
 
 
568
                                else {t.kind = noSym; goto done;}
 
569
 
 
570
                        case 28:
 
571
 
 
572
                                {t.kind = 36; goto done;}
 
573
 
 
574
                        case 29:
 
575
 
 
576
                                {t.kind = 38; goto done;}
 
577
 
 
578
                        case 30:
 
579
 
 
580
                                {t.kind = 39; goto done;}
 
581
 
 
582
                        case 31:
 
583
 
 
584
                                {t.kind = 41; goto done;}
 
585
 
 
586
                        case 32: {t.kind = 0; goto done;}
 
587
 
 
588
                }
 
589
 
 
590
                done: 
 
591
 
 
592
                t.val = buf.ToString();
 
593
 
 
594
                return t;
 
595
 
 
596
        }
 
597
 
 
598
        
 
599
 
 
600
        /* AW 2003-03-07 get the next token, move on and synch peek token with current */
 
601
 
 
602
        public static Token Scan () {
 
603
 
 
604
                t = pt = t.next;
 
605
 
 
606
                return t;
 
607
 
 
608
        }
 
609
 
 
610
 
 
611
 
 
612
        /* AW 2003-03-07 get the next token, ignore pragmas */
 
613
 
 
614
        public static Token Peek () {
 
615
 
 
616
                do {                      // skip pragmas while peeking
 
617
 
 
618
                        pt = pt.next;
 
619
 
 
620
                } while (pt != null && pt.kind > maxT);
 
621
 
 
622
                return pt;
 
623
 
 
624
        }
 
625
 
 
626
        
 
627
 
 
628
        /* AW 2003-03-11 to make sure peek start at current scan position */
 
629
 
 
630
        public static void StartPeek () { pt = t; }
 
631
 
 
632
} // end Scanner
 
633
 
 
634
 
 
635
 
 
636
 
 
637
 
 
638
public delegate void ErrorCodeProc (int line, int col, int n);
 
639
 
 
640
public delegate void ErrorMsgProc (int line, int col, string msg);
 
641
 
 
642
 
 
643
 
 
644
public class Errors {
 
645
 
 
646
        public static int count = 0;                                               // number of errors detected
 
647
 
 
648
        public static ErrorCodeProc SynErr = new ErrorCodeProc(DefaultCodeError);  // syntactic errors
 
649
 
 
650
        public static ErrorCodeProc SemErr = new ErrorCodeProc(DefaultCodeError);  // semantic errors
 
651
 
 
652
        public static ErrorMsgProc Error = new ErrorMsgProc(DefaultMsgError);      // user defined string based errors
 
653
 
 
654
        
 
655
 
 
656
        public static void Exception (string s) {
 
657
 
 
658
                Console.WriteLine(s); 
 
659
 
 
660
                System.Environment.Exit(0);
 
661
 
 
662
        }
 
663
 
 
664
 
 
665
 
 
666
        static void DefaultCodeError (int line, int col, int n) {
 
667
 
 
668
                Console.WriteLine("-- line {0} col {1}: error {2}", line, col, n);
 
669
 
 
670
                count++;
 
671
 
 
672
        }
 
673
 
 
674
 
 
675
 
 
676
        static void DefaultMsgError (int line, int col, string s) {
 
677
 
 
678
                Console.WriteLine("-- line {0} col {1}: {2}", line, col, s);
 
679
 
 
680
                count++;
 
681
 
 
682
        }
 
683
 
 
684
} // Errors
 
685
 
 
686
 
 
687
 
 
688
}