Lexer
using CLanguage.Parser.yyParser;
using System;
using System.Collections.Generic;
namespace CLanguage.Parser
{
public class Lexer : yyInput
{
private Preprocessor _pp;
private int _token = -1;
private object _value;
private int _lastR = 32;
private char[] _chbuf = new char[4096];
private int _chbuflen;
private Dictionary<string, int> _kwTokens = new Dictionary<string, int> {
{
"void",
300
},
{
"char",
290
},
{
"short",
291
},
{
"int",
292
},
{
"long",
293
},
{
"float",
296
},
{
"double",
297
},
{
"signed",
294
},
{
"unsigned",
295
},
{
"bool",
301
},
{
"struct",
304
},
{
"class",
305
},
{
"union",
306
},
{
"enum",
307
},
{
"typedef",
283
},
{
"extern",
284
},
{
"static",
285
},
{
"auto",
286
},
{
"register",
287
},
{
"inline",
288
},
{
"const",
298
},
{
"restrict",
289
},
{
"volatile",
299
},
{
"goto",
317
},
{
"continue",
318
},
{
"break",
319
},
{
"return",
320
},
{
"if",
311
},
{
"else",
312
},
{
"for",
316
},
{
"while",
314
}
};
public Report Report => _pp.Report;
public Func<string, bool> IsTypedef { get; set; }
public Lexer(Preprocessor pp)
{
_pp = pp;
}
public Lexer(string name, string code, Report report = null)
: this(new Preprocessor(name, code, report))
{
}
private bool Eof()
{
_value = null;
_token = -1;
return false;
}
public bool advance()
{
int num = _lastR;
bool flag = true;
while (flag) {
while (num >= 0 && num <= 32) {
num = _pp.Read();
}
flag = false;
if (num == 47 && _pp.Peek() == 47) {
int num2 = _pp.Read();
while (num2 > 0 && num2 != 10) {
num2 = _pp.Read();
}
num = _pp.Read();
flag = true;
}
}
if (num == -1)
return Eof();
char c = (char)num;
if (c == '_' || char.IsLetter(c)) {
_chbuf[0] = c;
_chbuflen = 0;
while (c == '_' || char.IsLetter(c) || char.IsDigit(c)) {
_chbuf[_chbuflen++] = c;
num = _pp.Read();
c = (char)num;
}
_lastR = num;
string text = (string)(_value = new string(_chbuf, 0, _chbuflen));
int value = 0;
if (_kwTokens.TryGetValue(text, out value))
_token = value;
else if (IsTypedef != null && IsTypedef(text)) {
_token = 282;
} else {
_token = 257;
}
} else if (!char.IsDigit(c)) {
switch (num) {
case 61:
num = _pp.Read();
if (num == 61) {
_token = 268;
_value = null;
_lastR = _pp.Read();
} else {
_token = 61;
_value = null;
_lastR = num;
}
break;
case 33:
case 37:
case 40:
case 41:
case 44:
case 58:
case 59:
case 63:
case 91:
case 93:
case 123:
case 125:
_token = num;
_value = null;
_lastR = _pp.Read();
break;
case 46: {
int num5 = _pp.Read();
if (num5 == 46 && _pp.Peek() == 46)
throw new NotImplementedException();
_token = num;
_value = null;
_lastR = num5;
break;
}
case 42:
case 47: {
int num4 = _pp.Read();
if (num4 == 61) {
_token = ((num == 42) ? 272 : 273);
_value = null;
_lastR = num4;
} else {
_token = num;
_value = null;
_lastR = num4;
}
break;
}
case 124: {
int num9 = _pp.Read();
switch (num9) {
case 124:
num9 = _pp.Read();
if (num9 == 61)
throw new NotImplementedException();
_token = 271;
_value = null;
_lastR = num9;
break;
case 61:
throw new NotImplementedException();
default:
_token = num;
_value = null;
_lastR = num9;
break;
}
break;
}
case 43: {
int num8 = _pp.Read();
switch (num8) {
case 61:
_token = 275;
_value = null;
_lastR = _pp.Read();
break;
case 43:
_token = 262;
_value = null;
_lastR = _pp.Read();
break;
default:
_token = num;
_value = null;
_lastR = num8;
break;
}
break;
}
case 45: {
int num7 = _pp.Read();
switch (num7) {
case 61:
_token = 276;
_value = null;
_lastR = _pp.Read();
break;
case 45:
_token = 263;
_value = null;
_lastR = _pp.Read();
break;
default:
_token = num;
_value = null;
_lastR = num7;
break;
}
break;
}
case 60: {
int num6 = _pp.Read();
if (num6 == 61) {
_token = 266;
_value = null;
_lastR = _pp.Read();
} else {
_token = num;
_value = null;
_lastR = num6;
}
break;
}
case 62: {
int num3 = _pp.Read();
if (num3 == 61) {
_token = 267;
_value = null;
_lastR = _pp.Read();
} else {
_token = num;
_value = null;
_lastR = num3;
}
break;
}
default:
throw new NotImplementedException();
}
} else {
bool flag2 = true;
bool flag3 = false;
bool flag4 = false;
bool flag5 = false;
_chbuf[0] = c;
_chbuflen = 0;
while (c == '.' || char.IsDigit(c) || c == 'E' || c == 'e' || c == 'f' || c == 'F' || c == 'u' || c == 'U' || c == 'l' || c == 'L') {
switch (c) {
case 'L':
case 'l':
flag3 = true;
break;
case 'U':
case 'u':
flag4 = true;
break;
case 'F':
case 'f':
flag5 = true;
break;
default:
flag2 &= char.IsDigit(c);
_chbuf[_chbuflen++] = c;
break;
}
num = _pp.Read();
c = (char)num;
}
_lastR = num;
string s = new string(_chbuf, 0, _chbuflen);
if (flag2) {
if (flag3) {
if (flag4)
_value = ulong.Parse(s);
else
_value = long.Parse(s);
} else if (flag4) {
_value = uint.Parse(s);
} else {
_value = int.Parse(s);
}
} else if (flag5) {
_value = float.Parse(s);
} else {
_value = double.Parse(s);
}
_token = 258;
}
return true;
}
public int token()
{
return _token;
}
public object value()
{
return _value;
}
}
}