lexer.cs
来自「全功能c#编译器」· CS 代码 · 共 767 行 · 第 1/2 页
CS
767 行
}
}
if (nextChar == -1) {
errors.Error(y, x, String.Format("End of file reached inside verbatim string literal"));
}
return new Token(Tokens.Literal, x, y, originalValue.ToString(), sb.ToString());
}
char[] escapeSequenceBuffer = new char[12];
string ReadEscapeSequence(out char ch)
{
int nextChar = reader.Read();
if (nextChar == -1) {
errors.Error(line, col, String.Format("End of file reached inside escape sequence"));
ch = '\0';
return String.Empty;
}
char c = (char)nextChar;
int curPos = 1;
escapeSequenceBuffer[0] = c;
++col;
switch (c) {
case '\'':
ch = '\'';
break;
case '\"':
ch = '\"';
break;
case '\\':
ch = '\\';
break;
case '0':
ch = '\0';
break;
case 'a':
ch = '\a';
break;
case 'b':
ch = '\b';
break;
case 'f':
ch = '\f';
break;
case 'n':
ch = '\n';
break;
case 'r':
ch = '\r';
break;
case 't':
ch = '\t';
break;
case 'v':
ch = '\v';
break;
case 'u':
case 'x':
c = (char)reader.Read();
int number = GetHexNumber(c);
if (number < 0) {
errors.Error(line, col, String.Format("Invalid char in literal : {0}", c));
}
escapeSequenceBuffer[curPos++] = c;
for (int i = 0; i < 3; ++i) {
if (IsHex((char)reader.Peek())) {
c = (char)reader.Read();
int idx = GetHexNumber(c);
escapeSequenceBuffer[curPos++] = c;
number = idx * (16 * (i + 1)) + number;
} else {
break;
}
}
ch = (char)number;
break;
default:
errors.Error(line, col, String.Format("Unexpected escape sequence : {0}", c));
ch = '\0';
break;
}
return new String(escapeSequenceBuffer, 0, curPos);
}
Token ReadChar()
{
int x = col;
int y = line;
int nextChar = reader.Read();
if (nextChar == -1) {
errors.Error(y, x, String.Format("End of file reached inside character literal"));
return null;
}
char ch = (char)nextChar;
++col;
string escapeSequence = String.Empty;
if (ch == '\\') {
escapeSequence = ReadEscapeSequence(out ch);
}
if ((char)reader.Read() != '\'') {
errors.Error(y, x, String.Format("Char not terminated"));
}
return new Token(Tokens.Literal, x, y, "'" + ch + escapeSequence + "'", ch);
}
Token ReadOperator(char ch)
{
int x = col;
int y = line;
++col;
switch (ch) {
case '+':
switch (reader.Peek()) {
case '+':
reader.Read();
++col;
return new Token(Tokens.Increment, x, y);
case '=':
reader.Read();
++col;
return new Token(Tokens.PlusAssign, x, y);
}
return new Token(Tokens.Plus, x, y);
case '-':
switch (reader.Peek()) {
case '-':
reader.Read();
++col;
return new Token(Tokens.Decrement, x, y);
case '=':
reader.Read();
++col;
return new Token(Tokens.MinusAssign, x, y);
case '>':
reader.Read();
++col;
return new Token(Tokens.Pointer, x, y);
}
return new Token(Tokens.Minus, x, y);
case '*':
switch (reader.Peek()) {
case '=':
reader.Read();
++col;
return new Token(Tokens.TimesAssign, x, y);
default:
break;
}
return new Token(Tokens.Times, x, y);
case '/':
switch (reader.Peek()) {
case '=':
reader.Read();
++col;
return new Token(Tokens.DivAssign, x, y);
}
return new Token(Tokens.Div, x, y);
case '%':
switch (reader.Peek()) {
case '=':
reader.Read();
++col;
return new Token(Tokens.ModAssign, x, y);
}
return new Token(Tokens.Mod, x, y);
case '&':
switch (reader.Peek()) {
case '&':
reader.Read();
++col;
return new Token(Tokens.LogicalAnd, x, y);
case '=':
reader.Read();
++col;
return new Token(Tokens.BitwiseAndAssign, x, y);
}
return new Token(Tokens.BitwiseAnd, x, y);
case '|':
switch (reader.Peek()) {
case '|':
reader.Read();
++col;
return new Token(Tokens.LogicalOr, x, y);
case '=':
reader.Read();
++col;
return new Token(Tokens.BitwiseOrAssign, x, y);
}
return new Token(Tokens.BitwiseOr, x, y);
case '^':
switch (reader.Peek()) {
case '=':
reader.Read();
++col;
return new Token(Tokens.XorAssign, x, y);
default:
break;
}
return new Token(Tokens.Xor, x, y);
case '!':
switch (reader.Peek()) {
case '=':
reader.Read();
++col;
return new Token(Tokens.NotEqual, x, y);
}
return new Token(Tokens.Not, x, y);
case '~':
return new Token(Tokens.BitwiseComplement, x, y);
case '=':
switch (reader.Peek()) {
case '=':
reader.Read();
++col;
return new Token(Tokens.Equal, x, y);
}
return new Token(Tokens.Assign, x, y);
case '<':
switch (reader.Peek()) {
case '<':
reader.Read();
if (reader.Peek() != -1) {
switch ((char)reader.Peek()) {
case '=':
reader.Read();
col += 2;
return new Token(Tokens.ShiftLeftAssign, x, y);
default:
++col;
break;
}
}
return new Token(Tokens.ShiftLeft, x, y);
case '=':
reader.Read();
++col;
return new Token(Tokens.LessEqual, x, y);
}
return new Token(Tokens.LessThan, x, y);
case '>':
switch (reader.Peek()) {
case '>':
reader.Read();
if (reader.Peek() != -1) {
switch ((char)reader.Peek()) {
case '=':
reader.Read();
col += 2;
return new Token(Tokens.ShiftRightAssign, x, y);
default:
++col;
break;
}
}
return new Token(Tokens.ShiftRight, x, y);
case '=':
reader.Read();
++col;
return new Token(Tokens.GreaterEqual, x, y);
}
return new Token(Tokens.GreaterThan, x, y);
case '?':
return new Token(Tokens.Question, x, y);
case ';':
return new Token(Tokens.Semicolon, x, y);
case ':':
return new Token(Tokens.Colon, x, y);
case ',':
return new Token(Tokens.Comma, x, y);
case '.':
if (Char.IsDigit((char)reader.Peek())) {
col -= 2;
return ReadDigit('.', col + 1);
}
return new Token(Tokens.Dot, x, y);
case ')':
return new Token(Tokens.CloseParenthesis, x, y);
case '(':
return new Token(Tokens.OpenParenthesis, x, y);
case ']':
return new Token(Tokens.CloseSquareBracket, x, y);
case '[':
return new Token(Tokens.OpenSquareBracket, x, y);
case '}':
return new Token(Tokens.CloseCurlyBrace, x, y);
case '{':
return new Token(Tokens.OpenCurlyBrace, x, y);
default:
--col;
return null;
}
}
void ReadComment()
{
++col;
switch (reader.Read()) {
case '*':
ReadMultiLineComment();
break;
case '/':
if (reader.Peek() == '/') {
reader.Read();
ReadSingleLineComment(CommentType.Documentation);
} else {
ReadSingleLineComment(CommentType.SingleLine);
}
break;
default:
errors.Error(line, col, String.Format("Error while reading comment"));
break;
}
}
string ReadCommentToEOL()
{
sb.Length = 0;
StringBuilder curWord = specialCommentHash != null ? new StringBuilder() : null;
int nextChar;
while ((nextChar = reader.Read()) != -1) {
char ch = (char)nextChar;
++col;
if (HandleLineEnd(ch)) {
return sb.ToString();;
}
if (specialCommentHash != null) {
if (Char.IsLetter(ch)) {
curWord.Append(ch);
} else {
string tag = curWord.ToString();
curWord = new StringBuilder();
if (specialCommentHash[tag] != null) {
Point p = new Point(col ,line);
string comment = ReadToEOL();
tagComments.Add(new TagComment(tag, comment, p));
sb.Append(tag);
sb.Append(comment);
return sb.ToString();
}
}
}
sb.Append(ch);
}
return sb.ToString();
}
void ReadSingleLineComment(CommentType commentType)
{
ReadCommentToEOL();
}
void ReadMultiLineComment()
{
int nextChar;
while ((nextChar = reader.Read()) != -1) {
char ch = (char)nextChar;
++col;
if (HandleLineEnd(ch)) {
continue;
}
// End of multiline comment reached ?
if (ch == '*' && reader.Peek() == '/') {
reader.Read();
++col;
return;
}
}
// Reached EOF before end of multiline comment.
errors.Error(line, col, String.Format("Reached EOF before the end of a multiline comment"));
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?