using System; using System.Text; using System.Collections.Generic; using System.Globalization; using System.Linq; namespace Lexer { public class LexerException : System.Exception { public LexerException(string msg) : base(msg) { } } public class Lexer { protected int position; protected char currentCh; // ��������� ��������� ������ protected int currentCharValue; // ����� �������� ���������� ���������� ������� protected System.IO.StringReader inputReader; protected string inputString; public Lexer(string input) { inputReader = new System.IO.StringReader(input); inputString = input; } public void Error() { System.Text.StringBuilder o = new System.Text.StringBuilder(); o.Append(inputString + '\n'); o.Append(new System.String(' ', position - 1) + "^\n"); o.AppendFormat("Error in symbol {0}", currentCh); throw new LexerException(o.ToString()); } protected void NextCh() { this.currentCharValue = this.inputReader.Read(); this.currentCh = (char) currentCharValue; this.position += 1; } public virtual bool Parse() { return true; } } public class IntLexer : Lexer { protected System.Text.StringBuilder intString; public int parseResult = 0; public IntLexer(string input) : base(input) { intString = new System.Text.StringBuilder(); } public override bool Parse() { NextCh(); int res = 0; // ��� ����� �������� ����� int sign = 1; // ���� ����� if (currentCh == '+' || currentCh == '-') { if (currentCh == '-') sign = -1; NextCh(); } if (char.IsDigit(currentCh)) { res = currentCh - '0'; NextCh(); } else { Error(); } while (char.IsDigit(currentCh)) { res = res * 10 + currentCh - '0'; NextCh(); } if (currentCharValue != -1) { Error(); } this.parseResult = res * sign; return true; } } public class IdentLexer : Lexer { private string parseResult; protected StringBuilder builder; public string ParseResult { get { return parseResult; } } public IdentLexer(string input) : base(input) { builder = new StringBuilder(); } public override bool Parse() { NextCh(); if (currentCharValue == -1) Error(); var builder1 = new StringBuilder(); if (char.IsLetter(currentCh) || currentCh == '_') { builder1.Append(currentCh); NextCh(); } else { Error(); return false; } while (char.IsLetter(currentCh) || char.IsDigit(currentCh) || currentCh == '_') { builder1.Append(currentCh); NextCh(); } if (currentCharValue != -1) { Error(); } parseResult = builder1.ToString(); return true; } } public class IntNoZeroLexer : IntLexer { public IntNoZeroLexer(string input) : base(input) { } public override bool Parse() { NextCh(); if (currentCharValue == -1) { Error(); } if (currentCh == '0') Error(); if (currentCh == '+' || currentCh == '-') { NextCh(); if (currentCh == '0') Error(); } while (char.IsDigit(currentCh)) NextCh(); if (currentCharValue != -1) { Error(); } return true; //throw new NotImplementedException(); } } public class LetterDigitLexer : Lexer { protected StringBuilder builder; protected string parseResult; public string ParseResult { get { return parseResult; } } public LetterDigitLexer(string input) : base(input) { builder = new StringBuilder(); } public override bool Parse() { //throw new NotImplementedException(); NextCh(); if (currentCharValue == -1) { Error(); } if (char.IsDigit(currentCh)) Error(); bool isDigit = false; NextCh(); while ((char.IsDigit(currentCh) && !isDigit) || (char.IsLetter(currentCh) && isDigit)) { isDigit = char.IsDigit(currentCh); NextCh(); } if (currentCharValue != -1) { Error(); } return true; } } public class LetterListLexer : Lexer { protected List<char> parseResult; public List<char> ParseResult { get { return parseResult; } } public LetterListLexer(string input) : base(input) { parseResult = new List<char>(); } public override bool Parse() { NextCh(); List<char> res = new List<char>(); if (currentCharValue == -1) { Error(); } if (!char.IsLetter(currentCh)) Error(); else { res.Add(currentCh); NextCh(); } while (currentCh == ',' || currentCh == ';') { NextCh(); if (char.IsLetter(currentCh)) res.Add(currentCh); else Error(); NextCh(); } if (currentCharValue != -1) { Error(); } parseResult = res; return true; } } public class DigitListLexer : Lexer { protected List<int> parseResult; public List<int> ParseResult { get { return parseResult; } } public DigitListLexer(string input) : base(input) { parseResult = new List<int>(); } public override bool Parse() { NextCh(); List<int> res = new List<int>(); if (currentCharValue == -1) { Error(); } if (!char.IsDigit(currentCh)) Error(); else { res.Add(currentCh - '0'); NextCh(); } while (currentCh == ' ') { NextCh(); if (char.IsDigit(currentCh)) { res.Add(currentCh - '0'); NextCh(); } else if (currentCh == ' ') continue; else Error(); } if (currentCharValue != -1) { Error(); } parseResult = res; return true; } } public class LetterDigitGroupLexer : Lexer { protected StringBuilder builder; protected string parseResult; public string ParseResult { get { return parseResult; } } public LetterDigitGroupLexer(string input) : base(input) { builder = new StringBuilder(); } public override bool Parse() { NextCh(); StringBuilder res = new StringBuilder(""); if (currentCharValue == -1) { Error(); } while (char.IsLetterOrDigit(currentCh)) { if (char.IsLetter(currentCh)) { res.Append(currentCh); NextCh(); } else Error(); if (char.IsLetter(currentCh)) { res.Append(currentCh); NextCh(); if (currentCharValue == -1) break; } if (char.IsDigit(currentCh)) { res.Append(currentCh); NextCh(); if (currentCharValue == -1) break; } if (char.IsDigit(currentCh)) { res.Append(currentCh); NextCh(); if (currentCharValue == -1) break; } } if (currentCharValue != -1) { Error(); } parseResult = res.ToString(); return true; } } public class DoubleLexer : Lexer { private StringBuilder builder; private double parseResult; public double ParseResult { get { return parseResult; } } public DoubleLexer(string input) : base(input) { builder = new StringBuilder(); } public override bool Parse() { NextCh(); StringBuilder res = new StringBuilder(""); if (currentCharValue == -1) { Error(); } if (char.IsDigit(currentCh)) { if (currentCh == '0') { res.Append(currentCh); NextCh(); if (currentCharValue == -1) { parseResult = double.Parse(res.ToString()); return true; } else if (currentCh != '.' && currentCharValue != -1) Error(); else if (currentCh == '.') { res.Append(currentCh); NextCh(); if (!char.IsDigit(currentCh)) Error(); } else Error(); } else { while (char.IsDigit(currentCh)) { res.Append(currentCh); NextCh(); } if (currentCharValue == -1) { parseResult = double.Parse(res.ToString()); return true; } else if (currentCh != '.' && currentCharValue != -1) Error(); else if (currentCh == '.') { res.Append(currentCh); NextCh(); if (!char.IsDigit(currentCh)) Error(); } else Error(); } } else Error(); while (char.IsDigit(currentCh)) { res.Append(currentCh); NextCh(); } if (currentCharValue != -1) { Error(); } parseResult = double.Parse(res.ToString()); return true; } } public class StringLexer : Lexer { private StringBuilder builder; private string parseResult; public string ParseResult { get { return parseResult; } } public StringLexer(string input) : base(input) { builder = new StringBuilder(); } public override bool Parse() { NextCh(); StringBuilder res = new StringBuilder(""); if (currentCharValue == -1) { Error(); } if (currentCh != '\'') Error(); res.Append(currentCh); NextCh(); while (currentCh != '\'') { if (currentCharValue == -1) Error(); res.Append(currentCh); NextCh(); } if (currentCh != '\'') Error(); res.Append(currentCh); NextCh(); if (currentCharValue != -1) { Error(); } parseResult = res.ToString(); return true; } } public class CommentLexer : Lexer { private StringBuilder builder; private string parseResult; public string ParseResult { get { return parseResult; } } public CommentLexer(string input) : base(input) { builder = new StringBuilder(); } public override bool Parse() { NextCh(); StringBuilder res = new StringBuilder(""); if (currentCharValue == -1) Error(); if (currentCh != '/') Error(); res.Append(currentCh); NextCh(); if (currentCh != '*') Error(); res.Append(currentCh); NextCh(); while (true) { if (currentCharValue == -1) Error(); if (currentCh == '*') { res.Append(currentCh); NextCh(); if (currentCh == '/') { res.Append(currentCh); NextCh(); if (currentCharValue != -1) Error(); break; } } res.Append(currentCh); NextCh(); } parseResult = res.ToString(); return true; } } public class IdentChainLexer : Lexer { private StringBuilder builder; private List<string> parseResult; public List<string> ParseResult { get { return parseResult; } } public IdentChainLexer(string input) : base(input) { builder = new StringBuilder(); parseResult = new List<string>(); } public override bool Parse() { NextCh(); StringBuilder res = new StringBuilder(""); StringBuilder ident = new StringBuilder(""); if (currentCharValue == -1) Error(); IdentLexer l = new IdentLexer("abc22"); return true; } } public class Program { public static void Main() { CommentLexer l = new CommentLexer("/**/"); l.Parse(); } } }