1 using System;
2 using System.Collections;
3 using System.IO;
4 using System.Text;
5
6 namespace soulcm.scm2html
7 {
8 public enum IdentifierClassKind
9 {
10 none, unicode, ascii
11 }
12
13 public class LexerContext
14 {
15 public LexerContext(IdentifierClassKind identifierClassKind) :
16 classIndex(0), any(), epsilon(eps), classMap(null), tokens(null), keywords(null), expressions(null), lexer(null), currentExpression(null), idStart(new Class(0)), idCont(new Class(0))
17 {
18 if (identifierClassKind == IdentifierClassKind.unicode)
19 {
20 MakeUnicodeIdentifierClasses(*this);
21 symbols.Add(idStart);
22 symbols.Add(idCont);
23 }
24 else if (identifierClassKind == IdentifierClassKind.ascii)
25 {
26 MakeAsciiIdentifierClasses(*this);
27 symbols.Add(idStart);
28 symbols.Add(idCont);
29 }
30 }
31 public ~LexerContext()
32 {
33 for (Symbol* symbol : symbols)
34 {
35 delete symbol;
36 }
37 }
38 public Symbol* MakeAny()
39 {
40 return &any;
41 }
42 public Symbol* MakeEpsilon()
43 {
44 return ε
45 }
46 public Class* MakeIdStart()
47 {
48 return idStart;
49 }
50 public Class* MakeIdCont()
51 {
52 return idCont;
53 }
54 public const List<Symbol*>& Symbols() const
55 {
56 return symbols;
57 }
58 public const string& FileName() const
59 {
60 return fileName;
61 }
62 public void SetCurrentExpression(Expression* currentExpression_)
63 {
64 currentExpression = currentExpression_;
65 }
66 public Symbol* MakeChar(uchar c)
67 {
68 Map<uchar, Symbol*>.ConstIterator it = charSymbols.CFind(c);
69 if (it != charSymbols.CEnd())
70 {
71 return it->second;
72 }
73 Symbol* symbol = new Char(c);
74 symbol->DontSetContained();
75 symbols.Add(symbol);
76 charSymbols[c] = symbol;
77 return symbol;
78 }
79 public Symbol* MakeRange(uchar start, uchar end)
80 {
81 Range range(start, end);
82 Map<Range, Symbol*>.ConstIterator it = rangeSymbols.CFind(range);
83 if (it != rangeSymbols.CEnd())
84 {
85 return it->second;
86 }
87 Symbol* symbol = new Range(start, end);
88 symbols.Add(symbol);
89 rangeSymbols[range] = symbol;
90 return symbol;
91 }
92 public Class* MakeClass()
93 {
94 Class* cls = new Class(classIndex++);
95 symbols.Add(cls);
96 return cls;
97 }
98 public void AddUsingNode(Cm.Ast.Node* usingNode)
99 {
100 usingNodes.Add(usingNode);
101 }
102 public void SetFileName(const string& fileName_)
103 {
104 fileName = fileName_;
105 }
106 private int nextNfaStateId;
107 private int nextDfaStateId;
108 private int lexerStatementIndex;
109 private int classIndex;
110 private string fileName;
111 private List<Symbol*> symbols;
112 private List<Class*> canonicalClasses;
113 private List<Class*> partition;
114 private List<Cm.Ast.Node*> usingNodes;
115 private Map<uchar, Symbol*> charSymbols;
116 private Map<Range, Symbol*> rangeSymbols;
117 private Any any;
118 private Char epsilon;
119 private Class* idStart;
120 private Class* idCont;
121 private ClassMap* classMap;
122 private Usings* usings;
123 private Tokens* tokens;
124 private Keywords* keywords;
125 private Expressions* expressions;
126 private Lexer* lexer;
127 private Expression* currentExpression;
128 }
129
130 public class ClassLess
131 {
132 public bool operator()(const Class* left, const Class* right) const
133 {
134 if (left->Ranges().Count() < right->Ranges().Count()) return false;
135 if (left->Ranges().Count() > right->Ranges().Count()) return false;
136 if (!left->Ranges().IsEmpty())
137 {
138 Range leftRange = left->Ranges().Front();
139 Range rightRange = right->Ranges().Front();
140 return leftRange < rightRange;
141 }
142 return false;
143 }
144 }
145
146 public class ClassesEqual
147 {
148 public bool operator()(const Class* left, const Class* right) const
149 {
150 return left->Ranges() == right->Ranges();
151 }
152 }
153 }