5
using System.Collections;
11
namespace at.jku.ssw.Coco {
17
public int kind; // token kind
19
public int pos; // token position in the source text (starting at 0)
21
public int col; // token column (starting at 0)
23
public int line; // token line (starting at 1)
25
public string val; // token value
27
public Token next; // AW 2003-03-07 Tokens are kept in linked list
33
public Token (int kind) { this.kind = kind; }
41
public const int eof = '\uffff';
46
public static string fileName;
48
public static int CountLines(int offset)
51
for (int i = 0; i <= offset; ++i) {
59
public static void Fill (string fileName) {
60
Buffer.fileName = fileName;
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);
69
} catch (IOException) {
71
Console.WriteLine("--- Cannot open file {0}", fileName);
73
System.Environment.Exit(0);
77
if (s != null) s.Close();
85
public static int Read () {
87
if (pos < bufLen) return buf[pos++];
95
public static int Peek () {
97
if (pos < bufLen) return buf[pos];
105
/* AW 2003-03-10 moved this from ParserGen.cs */
107
public static string GetString (int beg, int end) {
109
StringBuilder s = new StringBuilder(64);
111
int oldPos = Buffer.Pos;
115
while (beg < end) { s.Append((char)Buffer.Read()); beg++; }
125
public static int Pos {
131
if (value < 0) pos = 0;
133
else if (value >= bufLen) pos = bufLen;
145
public class Scanner {
147
const char EOF = '\0';
149
const char EOL = '\n';
157
const int noSym = 42;
159
static short[] start = {
161
32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
163
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
165
0, 27, 11, 0, 10, 0, 0, 5, 21, 22, 0, 15, 0, 16, 14, 0,
167
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 31, 18, 13, 19, 0,
169
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
171
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 0, 24, 0, 0,
173
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
175
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 20, 26, 0, 0,
177
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
179
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
181
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
183
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
187
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
189
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
191
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
199
static Token t; // current token
201
static char ch; // current input character
203
static int pos; // column number of current character
205
static int line; // line number of current character
207
static int lineStart; // start position of current line
209
static int oldEols; // EOLs that appeared in a comment;
211
static BitArray ignore; // set of characters to be ignored by the scanner
217
static Token tokens; // the complete input token stream
219
static Token pt; // current peek token
223
static int peekCount = 0;
227
public static int PeekCount { get { return peekCount; } }
231
public static void Init (String fileName) {
233
Buffer.Fill(fileName);
235
pos = -1; line = 1; lineStart = 0;
241
ignore = new BitArray(256);
243
ignore[9] = true; ignore[10] = true; ignore[13] = true; ignore[32] = true;
249
/* AW 2003-03-07 fill token list */
251
tokens = new Token(); // first token is a dummy
257
node.next = NextToken();
261
} while (node.kind != 0); /* AW: 0 => EOF */
269
static void NextCh() {
271
if (oldEols > 0) { ch = EOL; oldEols--; }
275
ch = (char)Buffer.Read(); pos++;
277
// replace isolated '\r' by '\n' in order to make
279
// eol handling uniform across Windows, Unix and Mac
281
if (ch == '\r' && Buffer.Peek() != '\n') ch = EOL;
283
else if (ch > '\u007f') ch = '?';
285
if (ch == EOL) { line++; lineStart = pos + 1; }
294
static bool Comment0() {
296
int level = 1, line0 = line, lineStart0 = lineStart;
314
if (level == 0) { oldEols = line - line0; NextCh(); return true; }
320
} else if (ch == '/') {
330
} else if (ch == EOF) return false;
338
if (ch==EOL) {line--; lineStart = lineStart0;}
340
pos = pos - 2; Buffer.Pos = pos+1; NextCh();
352
static void CheckLiteral() {
356
case "COMPILER": t.kind = 6; break;
358
case "PRODUCTIONS": t.kind = 7; break;
360
case "END": t.kind = 10; break;
362
case "CHARACTERS": t.kind = 11; break;
364
case "TOKENS": t.kind = 12; break;
366
case "PRAGMAS": t.kind = 13; break;
368
case "COMMENTS": t.kind = 14; break;
370
case "FROM": t.kind = 15; break;
372
case "TO": t.kind = 16; break;
374
case "NESTED": t.kind = 17; break;
376
case "IGNORE": t.kind = 18; break;
378
case "TOKENNAMES": t.kind = 19; break;
380
case "ANY": t.kind = 23; break;
382
case "WEAK": t.kind = 27; break;
384
case "SYNC": t.kind = 34; break;
386
case "IF": t.kind = 35; break;
388
case "CONTEXT": t.kind = 37; break;
390
case "using": t.kind = 40; break;
402
/* AW Scan() renamed to NextToken() */
404
static Token NextToken() {
406
while (ignore[ch]) NextCh();
408
if (ch == '/' && Comment0()) return NextToken();
412
t.pos = pos; t.col = pos - lineStart + 1; t.line = line;
414
int state = start[ch];
416
StringBuilder buf = new StringBuilder(16);
418
buf.Append(ch); NextCh();
424
case 0: { t.kind = noSym; goto done; } // NextCh already done
428
if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 1;}
430
else {t.kind = 1; t.val = buf.ToString(); CheckLiteral(); return t;}
434
if ((ch >= '0' && ch <= '9')) {buf.Append(ch); NextCh(); goto case 2;}
436
else {t.kind = 2; goto done;}
440
{t.kind = 3; goto done;}
444
{t.kind = 4; goto done;}
448
if ((ch >= 1 && ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '&' || ch >= '(' && ch <= '[' || ch >= ']')) {buf.Append(ch); NextCh(); goto case 6;}
450
else if (ch == 92) {buf.Append(ch); NextCh(); goto case 7;}
452
else {t.kind = noSym; goto done;}
456
if (ch == 39) {buf.Append(ch); NextCh(); goto case 9;}
458
else {t.kind = noSym; goto done;}
462
if ((ch >= ' ' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 8;}
464
else {t.kind = noSym; goto done;}
468
if ((ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'f')) {buf.Append(ch); NextCh(); goto case 8;}
470
else if (ch == 39) {buf.Append(ch); NextCh(); goto case 9;}
472
else {t.kind = noSym; goto done;}
476
{t.kind = 5; goto done;}
480
if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 10;}
482
else {t.kind = 43; goto done;}
486
if ((ch >= 1 && ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']')) {buf.Append(ch); NextCh(); goto case 11;}
488
else if ((ch == 10 || ch == 13)) {buf.Append(ch); NextCh(); goto case 4;}
490
else if (ch == '"') {buf.Append(ch); NextCh(); goto case 3;}
492
else if (ch == 92) {buf.Append(ch); NextCh(); goto case 12;}
494
else {t.kind = noSym; goto done;}
498
if ((ch >= ' ' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 11;}
500
else {t.kind = noSym; goto done;}
504
{t.kind = 8; goto done;}
508
if (ch == '.') {buf.Append(ch); NextCh(); goto case 17;}
510
else if (ch == ')') {buf.Append(ch); NextCh(); goto case 30;}
512
else {t.kind = 9; goto done;}
516
{t.kind = 20; goto done;}
520
{t.kind = 21; goto done;}
524
{t.kind = 22; goto done;}
528
{t.kind = 24; goto done;}
532
{t.kind = 25; goto done;}
536
{t.kind = 26; goto done;}
540
if (ch == '.') {buf.Append(ch); NextCh(); goto case 29;}
542
else {t.kind = 28; goto done;}
546
{t.kind = 29; goto done;}
550
{t.kind = 30; goto done;}
554
{t.kind = 31; goto done;}
558
{t.kind = 32; goto done;}
562
{t.kind = 33; goto done;}
566
if (ch == '=') {buf.Append(ch); NextCh(); goto case 28;}
568
else {t.kind = noSym; goto done;}
572
{t.kind = 36; goto done;}
576
{t.kind = 38; goto done;}
580
{t.kind = 39; goto done;}
584
{t.kind = 41; goto done;}
586
case 32: {t.kind = 0; goto done;}
592
t.val = buf.ToString();
600
/* AW 2003-03-07 get the next token, move on and synch peek token with current */
602
public static Token Scan () {
612
/* AW 2003-03-07 get the next token, ignore pragmas */
614
public static Token Peek () {
616
do { // skip pragmas while peeking
620
} while (pt != null && pt.kind > maxT);
628
/* AW 2003-03-11 to make sure peek start at current scan position */
630
public static void StartPeek () { pt = t; }
638
public delegate void ErrorCodeProc (int line, int col, int n);
640
public delegate void ErrorMsgProc (int line, int col, string msg);
644
public class Errors {
646
public static int count = 0; // number of errors detected
648
public static ErrorCodeProc SynErr = new ErrorCodeProc(DefaultCodeError); // syntactic errors
650
public static ErrorCodeProc SemErr = new ErrorCodeProc(DefaultCodeError); // semantic errors
652
public static ErrorMsgProc Error = new ErrorMsgProc(DefaultMsgError); // user defined string based errors
656
public static void Exception (string s) {
658
Console.WriteLine(s);
660
System.Environment.Exit(0);
666
static void DefaultCodeError (int line, int col, int n) {
668
Console.WriteLine("-- line {0} col {1}: error {2}", line, col, n);
676
static void DefaultMsgError (int line, int col, string s) {
678
Console.WriteLine("-- line {0} col {1}: {2}", line, col, s);