1 using System;
  2 using System.Collections;
  3 using System.IO;
  4 using System.Text;
  5 
  6 // this file has been semiautomatically generated from 'D:/work/soulngcm/soulngcm/sngcmlg/LexerContext.hpp' using cpp2cm version 1.0.0
  7 
  8 // this file has been semiautomatically generated from 'D:/work/soulngcm/soulngcm/sngcmlg/LexerContext.cpp' using cpp2cm version 1.0.0
  9 
 10 namespace soulcm.scmlg
 11 {
 12     public enum IdentifierClassKind
 13     {
 14         noneunicodeascii
 15     }
 16     public class LexerContext
 17     {
 18         public LexerContext(IdentifierClassKind identifierClassKind) : 
 19             nextNfaStateId(0)nextDfaStateId(0)lexerStatementIndex(-1)classIndex(0)any()epsilon(eps)
 20             idStart(new Class(classIndex++))idCont(new Class(classIndex++))
 21             classMap(null)tokens(null)keywords(null)expressions(null)lexer(null)parser(null)currentExpression(null)
 22             moduleId(Uuid.Random())
 23         {
 24             if (identifierClassKind == IdentifierClassKind.unicode)
 25             {
 26                 MakeUnicodeIdentifierClasses(*this);
 27                 symbols.Add(idStart);
 28                 symbols.Add(idCont);
 29             }
 30             else if (identifierClassKind == IdentifierClassKind.ascii)
 31             {
 32                 MakeAsciiIdentifierClasses(*this);
 33                 symbols.Add(idStart);
 34                 symbols.Add(idCont);
 35             }
 36         }
 37         public ~LexerContext()
 38         {
 39             for (NfaState* state : nfaStates)
 40             {
 41                 delete state;
 42             }
 43             for (DfaState* state : dfaStates)
 44             {
 45                 delete state;
 46             }
 47             for (Symbol* symbol : symbols)
 48             {
 49                 delete symbol;
 50             }
 51             for (Class* cls : canonicalClasses)
 52             {
 53                 delete cls;
 54             }
 55         }
 56         public const List<NfaState*>& NfaStates() const
 57         {
 58             return nfaStates;
 59         }
 60         public Symbol* MakeAny()
 61         {
 62             return &any;
 63         }
 64         public Symbol* MakeEpsilon()
 65         {
 66             return &epsilon;
 67         }
 68         public Class* MakeIdStart()
 69         {
 70             return idStart;
 71         }
 72         public Class* MakeIdCont()
 73         {
 74             return idCont;
 75         }
 76         public const List<Symbol*>& Symbols() const
 77         {
 78             return symbols;
 79         }
 80         public const string& FileName() const
 81         {
 82             return fileName;
 83         }
 84         public ClassMap* GetClassMap() const
 85         {
 86             return classMap;
 87         }
 88         public const List<Cm.Ast.Node*>& GetUsingNodes() const
 89         {
 90             return usingNodes;
 91         }
 92         public Tokens* GetTokens() const
 93         {
 94             return tokens;
 95         }
 96         public Keywords* GetKeywords() const
 97         {
 98             return keywords;
 99         }
100         public void SetLexer(Lexer* lexer_)
101         {
102             lexer = lexer_;
103         }
104         public Lexer* GetLexer() const
105         {
106             return lexer;
107         }
108         public void SetParser(Parser* parser_)
109         {
110             parser = parser_;
111         }
112         public Parser* GetParser() const
113         {
114             return parser;
115         }
116         public void SetCurrentExpression(Expression* currentExpression_)
117         {
118             currentExpression = currentExpression_;
119         }
120         public const List<Class*>& Partition() const
121         {
122             return partition;
123         }
124         public void SetApi(const ustring& api_)
125         {
126             api = api_;
127         }
128         public const ustring& Api() const
129         {
130             return api;
131         }
132         public NfaState* MakeNfaState()
133         {
134             NfaState* state = new NfaState(nextNfaStateId++lexerStatementIndex);
135             nfaStates.Add(state);
136             return state;
137         }
138         public DfaState* MakeDfaState(const List<NfaState*>& nfaStates)
139         {
140             List<NfaState*> s(nfaStates);
141             Sort(s.Begin()s.End());
142             for (DfaState* state : dfaStates)
143             {
144                 if (state->NfaStates() == s)
145                 {
146                     return state;
147                 }
148             }
149             DfaState* state = new DfaState(nextDfaStateId++s);
150             dfaStates.Add(state);
151             return state;
152         }
153         public Symbol* MakeChar(uchar c)
154         {
155             Map<ucharSymbol*>.ConstIterator it = charSymbols.CFind(c);
156             if (it != charSymbols.CEnd())
157             {
158                 return it->second;
159             }
160             Symbol* symbol = new Char(c);
161             symbol->DontSetContained();
162             symbols.Add(symbol);
163             charSymbols[c] = symbol;
164             return symbol;
165         }
166         public Symbol* MakeRange(uchar startuchar end)
167         {
168             Range range(startend);
169             Map<RangeSymbol*>.ConstIterator it = rangeSymbols.CFind(range);
170             if (it != rangeSymbols.CEnd())
171             {
172                 return it->second;
173             }
174             Symbol* symbol = new Range(startend);
175             symbols.Add(symbol);
176             rangeSymbols[range] = symbol;
177             return symbol;
178         }
179         public Class* MakeClass()
180         {
181             Class* cls = new Class(classIndex++);
182             symbols.Add(cls);
183             return cls;
184         }
185         public void SetClassMap(ClassMap* classMap_)
186         {
187             if ((classMap != null))
188             {
189                 throw Exception("error in " + fileName + ": cannot have more than one class map declaration per .lexer file");
190             }
191             classMap = classMap_;
192         }
193         public void AddUsingNode(Cm.Ast.Node* usingNode)
194         {
195             usingNodes.Add(usingNode);
196         }
197         public void SetTokens(Tokens* tokens_)
198         {
199             if ((tokens != null))
200             {
201                 throw Exception("error in " + fileName + ": cannot have more than one set of token definitions per .lexer file");
202             }
203             tokens = tokens_;
204         }
205         public void SetKeywords(Keywords* keywords_)
206         {
207             if ((keywords != null))
208             {
209                 throw Exception("error in " + fileName + ": cannot have more than one set of keyword definitions per .lexer file");
210             }
211             keywords = keywords_;
212         }
213         public void SetExpressions(Expressions* expressions_)
214         {
215             if ((expressions != null))
216             {
217                 throw Exception("error in " + fileName + ": cannot have more than one set of expressions per .lexer file");
218             }
219             expressions = expressions_;
220         }
221         public void SetFileName(const string& fileName_)
222         {
223             fileName = fileName_;
224         }
225         public Nfa MakeExpr(const ustring& id)
226         {
227             if (id == u"idstart")
228             {
229                 return MakeNfa(*thisMakeIdStart());
230             }
231             else if (id == u"idcont")
232             {
233                 return MakeNfa(*thisMakeIdCont());
234             }
235             if ((expressions != null))
236             {
237                 Expression* expr = expressions->Get(id);
238                 if ((currentExpression != null))
239                 {
240                     if (expr->Index() >= currentExpression->Index())
241                     {
242                         throw Exception("error: forward reference \'" + ToUtf8(expr->Id()) + "\' from expression \'" + ToUtf8(currentExpression->Id()) + "\'");
243                     }
244                 }
245                 if ((parser != null))
246                 {
247                     Expression* prevExpression = currentExpression;
248                     currentExpression = expr;
249                     Nfa nfa = parser->Parse(expr->Value()thisexpr->Line());
250                     currentExpression = prevExpression;
251                     return nfa;
252                 }
253                 else
254                 {
255                     throw Exception("parser not set");
256                 }
257             }
258             else
259             {
260                 throw Exception("expressions not set");
261             }
262         }
263         public void MakeCanonicalClasses()
264         {
265             List<Symbol*> s = symbols;
266             for (Symbol* symbol : s)
267             {
268                 if (symbol->Contained()) continue;
269                 if (symbol->IsClass())
270                 {
271                     Class* cls = cast<Class*>(symbol);
272                     Class* canonicalClass = cls->MakeCanonical(*this);
273                     canonicalClasses.Add(canonicalClass);
274                 }
275                 else if (symbol->IsChar())
276                 {
277                     Char* chr = cast<Char*>(symbol);
278                     Class* canonicalClass = new Class(-1);
279                     canonicalClass->Ranges().Add(Range(chr->Chr()chr->Chr()));
280                     canonicalClasses.Add(canonicalClass);
281                 }
282                 else if (symbol->IsAny())
283                 {
284                     Symbol* range = MakeRange(cast<uchar>(1)cast<uchar>(1114111));
285                     Class* canonicalClass = new Class(-1);
286                     canonicalClass->Ranges().Add(Range(cast<uchar>(1)cast<uchar>(1114111)));
287                     canonicalClasses.Add(canonicalClass);
288                 }
289                 else if (symbol->IsRange())
290                 {
291                     Range* range = cast<Range*>(symbol);
292                     Class* canonicalClass = new Class(-1);
293                     canonicalClass->Ranges().Add(*range);
294                     canonicalClasses.Add(canonicalClass);
295                 }
296             }
297             for (Class* canonicalClass : canonicalClasses)
298             {
299                 for (const Range& range : canonicalClass->Ranges())
300                 {
301                     if (canonicalClass->Chars().IsEmpty())
302                     {
303                         canonicalClass->AddChar(range.Start());
304                     }
305                     break;
306                 }
307             }
308         }
309         public void MakeClassPartition(bool debug)
310         {
311             LinkedList<Class*> classes;
312             for (Class* cls : canonicalClasses)
313             {
314                 classes.Add(cls);
315             }
316             LinkedList<Class*>.Iterator classIt = classes.Begin();
317             while (classIt != classes.End())
318             {
319                 bool classChanged = false;
320                 Class* cls = *classIt;
321                 LinkedList<Class*>.Iterator sourceIt = classes.Begin();
322                 while (!cls->Ranges().IsEmpty() && sourceIt != classes.End())
323                 {
324                     if (sourceIt == classIt)
325                     {
326                         ++sourceIt;
327                         continue;
328                     }
329                     bool sourceChanged = false;
330                     Class* source = *sourceIt;
331                     UniquePtr<Class> splitClass(new Class(-1));
332                     LinkedList<Range>.Iterator leftIt = cls->Ranges().Begin();
333                     while (leftIt != cls->Ranges().End())
334                     {
335                         bool leftChanged = false;
336                         LinkedList<Range>.Iterator rightIt = source->Ranges().Begin();
337                         while (leftIt != cls->Ranges().End() && rightIt != source->Ranges().End())
338                         {
339                             bool rightChanged = false;
340                             if (Intersect(*leftIt*rightIt))
341                             {
342                                 List<Range> leftRanges = *leftIt - *rightIt;
343                                 List<Range> rightRanges = *rightIt - *leftIt;
344                                 Range intersection = *leftIt & *rightIt;
345                                 for (const Range& leftRange : leftRanges)
346                                 {
347                                     if (leftRange.IsEmpty()) continue;
348                                     LinkedList<Range>.Iterator it = leftIt;
349                                     ++it;
350                                     cls->Ranges().Insert(itleftRange);
351                                 }
352                                 leftIt = cls->Ranges().Remove(leftIt);
353                                 leftChanged = true;
354                                 if (!intersection.IsEmpty())
355                                 {
356                                     splitClass->Ranges().Add(intersection);
357                                 }
358                                 for (const Range& rightRange : rightRanges)
359                                 {
360                                     if (rightRange.IsEmpty()) continue;
361                                     LinkedList<Range>.Iterator it = rightIt;
362                                     ++it;
363                                     source->Ranges().Insert(itrightRange);
364                                 }
365                                 rightIt = source->Ranges().Remove(rightIt);
366                                 rightChanged = true;
367                             }
368                             if (!rightChanged)
369                             {
370                                 ++rightIt;
371                             }
372                         }
373                         if (!leftChanged)
374                         {
375                             ++leftIt;
376                         }
377                     }
378                     if (source->Ranges().IsEmpty())
379                     {
380                         sourceIt = classes.Remove(sourceIt);
381                         sourceChanged = true;
382                     }
383                     if (!splitClass->Ranges().IsEmpty())
384                     {
385                         classes.Insert(sourceItsplitClass.Get());
386                         symbols.Add(splitClass.Release());
387                         sourceChanged = true;
388                     }
389                     if (!sourceChanged)
390                     {
391                         ++sourceIt;
392                     }
393                 }
394                 if (cls->Ranges().IsEmpty())
395                 {
396                     classIt = classes.Remove(classIt);
397                     classChanged = true;
398                 }
399                 if (!classChanged)
400                 {
401                     ++classIt;
402                 }
403             }
404             for (Class* cls : classes)
405             {
406                 cls->MakeMinimal(*this);
407                 partition.Add(cls);
408             }
409             for (int i = 0; i < partition.Count(); ++i;)
410             {
411                 Class* cls = partition[i];
412                 cls->SetIndex(i);
413             }
414             if (debug)
415             {
416                 CodeFormatter formatter(Console.Out());
417                 formatter.WriteLine("partition:");
418                 for (int i = 0; i < partition.Count(); ++i;)
419                 {
420                     Class* cls = partition[i];
421                     formatter.Write(ToString(cls->Index()));
422                     formatter.Write(" : ");
423                     cls->Print(formatter);
424                     formatter.WriteLine();
425                 }
426             }
427         }
428         public void MakeClassMap(const string& rootbool verbosebool noClassMapCompression)
429         {
430             List<int> classMapVec(1114112-1);
431             for (Class* cls : partition)
432             {
433                 for (const Range& range : cls->Ranges())
434                 {
435                     for (uchar i = range.Start(); i <= range.End(); i = cast<uchar>(cast<int>(i) + 1);)
436                     {
437                         if (classMapVec[cast<int>(i)] == -1)
438                         {
439                             classMapVec[cast<int>(i)] = cls->Index();
440                         }
441                     }
442                 }
443             }
444             string classMapName = "ClassMap";
445             if ((classMap != null))
446             {
447                 classMapName = ToUtf8(classMap->Name());
448             }
449             string classMapSourceFileName = GetFullPath(Path.Combine(rootclassMapName + ".cm"));
450             Cm.Ast.CompileUnitNode classMapUnit(System.Lex.Span()moduleIdclassMapSourceFileName);
451             classMapUnit.GlobalNs()->AddMember(new Cm.Ast.NamespaceImportNode(System.Lex.Span()moduleIdnew Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"System")));
452             classMapUnit.GlobalNs()->AddMember(new Cm.Ast.CommentNode(System.Lex.Span()moduleIdu"this file has been automatically generated from \'" + ToUtf32(FileName()) + u"\' using soulcm lexer generator scmlg version " + ToUtf32(LexerGeneratorVersionStr())));
453             UniquePtr<Cm.Ast.GlobalVariableNode> classMapDataVariable(new Cm.Ast.GlobalVariableNode(System.Lex.Span()moduleIdCm.Ast.Specifiers.private_new Cm.Ast.ArrayNode(System.Lex.Span()moduleIdnew Cm.Ast.ByteNode(System.Lex.Span()moduleId)null)new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"classMapData")&classMapUnit));
454             UniquePtr<Cm.Ast.ArrayLiteralNode> arrayLiteral(new Cm.Ast.ArrayLiteralNode(System.Lex.Span()moduleId));
455             SharedPtr<ByteStream> stream = System.Lex.MakeClassMapData(classMapVec!noClassMapCompression);
456             int x = stream->ReadByte();
457             while (x != -1)
458             {
459                 arrayLiteral->AddValue(new Cm.Ast.ByteLiteralNode(System.Lex.Span()moduleIdcast<byte>(x)));
460                 x = stream->ReadByte();
461             }
462             classMapDataVariable->SetInitializer(arrayLiteral.Release());
463             classMapUnit.GlobalNs()->AddMember(classMapDataVariable.Release());
464             UniquePtr<Cm.Ast.GlobalVariableNode> classMapVariable(new Cm.Ast.GlobalVariableNode(System.Lex.Span()moduleIdCm.Ast.Specifiers.private_new Cm.Ast.PointerNode(System.Lex.Span()moduleIdnew Cm.Ast.IntNode(System.Lex.Span()moduleId))new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"classMap")&classMapUnit));
465             classMapVariable->SetInitializer(new Cm.Ast.NullLiteralNode(System.Lex.Span()moduleId));
466             classMapUnit.GlobalNs()->AddMember(classMapVariable.Release());
467             UniquePtr<Cm.Ast.GlobalVariableNode> classMapCompressedVariable(new Cm.Ast.GlobalVariableNode(System.Lex.Span()moduleIdCm.Ast.Specifiers.private_new Cm.Ast.BoolNode(System.Lex.Span()moduleId)new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"classMapDataCompressed")&classMapUnit));
468             classMapCompressedVariable->SetInitializer(new Cm.Ast.BooleanLiteralNode(System.Lex.Span()moduleId!noClassMapCompression));
469             classMapUnit.GlobalNs()->AddMember(classMapCompressedVariable.Release());
470             UniquePtr<Cm.Ast.ClassNode> cls(new Cm.Ast.ClassNode(System.Lex.Span()moduleIdCm.Ast.Specifiers.public_ | Cm.Ast.Specifiers.static_new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdToUtf32(classMapName))null));
471             UniquePtr<Cm.Ast.MemberFunctionNode> initMemFun(new Cm.Ast.MemberFunctionNode(System.Lex.Span()moduleIdCm.Ast.Specifiers.public_ | Cm.Ast.Specifiers.static_new Cm.Ast.VoidNode(System.Lex.Span()moduleId)u"Init"null));
472             UniquePtr<Cm.Ast.CompoundStatementNode> initMemFunBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span()moduleId));
473             UniquePtr<Cm.Ast.CompoundStatementNode> initMemFunThenS(new Cm.Ast.CompoundStatementNode(System.Lex.Span()moduleId));
474             UniquePtr<Cm.Ast.InvokeNode> initMemFunInvoke(new Cm.Ast.InvokeNode(System.Lex.Span()moduleIdnew Cm.Ast.DotNode(System.Lex.Span()moduleId
475                 new Cm.Ast.DotNode(System.Lex.Span()moduleIdnew Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"System")new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"Lex"))
476                 new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"CreateClassMap"))));
477             initMemFunInvoke->AddArgument(new Cm.Ast.InvokeNode(System.Lex.Span()moduleId
478                 new Cm.Ast.DotNode(System.Lex.Span()moduleIdnew Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"classMapData")
479                     new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"Begin"))));
480             initMemFunInvoke->AddArgument(new Cm.Ast.InvokeNode(System.Lex.Span()moduleId
481                 new Cm.Ast.DotNode(System.Lex.Span()moduleIdnew Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"classMapData")new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"Length"))));
482             initMemFunInvoke->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"classMapDataCompressed"));
483             UniquePtr<Cm.Ast.AssignmentStatementNode> initMemFunAssigmentStmt(new Cm.Ast.AssignmentStatementNode(System.Lex.Span()moduleIdnew Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"classMap")
484                 initMemFunInvoke.Release()));
485             initMemFunThenS->AddStatement(initMemFunAssigmentStmt.Release());
486             UniquePtr<Cm.Ast.IfStatementNode> initMemFunIfStmt(new Cm.Ast.IfStatementNode(System.Lex.Span()moduleId
487                 new Cm.Ast.EqualNode(System.Lex.Span()moduleId
488                     new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"classMap")new Cm.Ast.NullLiteralNode(System.Lex.Span()moduleId))
489                 initMemFunThenS.Release()null));
490             initMemFunBody->AddStatement(initMemFunIfStmt.Release());
491             initMemFun->SetBody(initMemFunBody.Release());
492             cls->AddMember(initMemFun.Release());
493             UniquePtr<Cm.Ast.MemberFunctionNode> getClassMemFun(new Cm.Ast.MemberFunctionNode(System.Lex.Span()moduleIdCm.Ast.Specifiers.public_ | Cm.Ast.Specifiers.static_new Cm.Ast.IntNode(System.Lex.Span()moduleId)u"GetClass"null));
494             getClassMemFun->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span()moduleIdnew Cm.Ast.UCharNode(System.Lex.Span()moduleId)new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"c")));
495             UniquePtr<Cm.Ast.CompoundStatementNode> body(new Cm.Ast.CompoundStatementNode(System.Lex.Span()moduleId));
496             UniquePtr<Cm.Ast.ConstructionStatementNode> constructStmt(new Cm.Ast.ConstructionStatementNode(System.Lex.Span()moduleIdnew Cm.Ast.IntNode(System.Lex.Span()moduleId)new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"i")));
497             constructStmt->SetAssignment();
498             constructStmt->AddArgument(new Cm.Ast.CastNode(System.Lex.Span()moduleIdnew Cm.Ast.IntNode(System.Lex.Span()moduleId)new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"c")));
499             body->AddStatement(constructStmt.Release());
500             UniquePtr<Cm.Ast.CompoundStatementNode> thenS(new Cm.Ast.CompoundStatementNode(System.Lex.Span()moduleId));
501             UniquePtr<Cm.Ast.ReturnStatementNode> returnClassMapI(new Cm.Ast.ReturnStatementNode(System.Lex.Span()moduleIdnew Cm.Ast.IndexingNode(System.Lex.Span()moduleIdnew Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"classMap")new Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"i"))));
502             thenS->AddStatement(returnClassMapI.Release());
503             UniquePtr<Cm.Ast.CompoundStatementNode> elseS(new Cm.Ast.CompoundStatementNode(System.Lex.Span()moduleId));
504             UniquePtr<Cm.Ast.ReturnStatementNode> returnMinusOne(new Cm.Ast.ReturnStatementNode(System.Lex.Span()moduleIdnew Cm.Ast.IntLiteralNode(System.Lex.Span()moduleId-1)));
505             elseS->AddStatement(returnMinusOne.Release());
506             UniquePtr<Cm.Ast.IfStatementNode> ifStmt(new Cm.Ast.IfStatementNode(System.Lex.Span()moduleIdnew Cm.Ast.LessNode(System.Lex.Span()moduleIdnew Cm.Ast.IdentifierNode(System.Lex.Span()moduleIdu"i")new Cm.Ast.IntLiteralNode(System.Lex.Span()moduleId1114112))thenS.Release()elseS.Release()));
507             body->AddStatement(ifStmt.Release());
508             getClassMemFun->SetBody(body.Release());
509             cls->AddMember(getClassMemFun.Release());
510             classMapUnit.GlobalNs()->AddMember(cls.Release());
511             System.IO.StreamWriter classMapFile(System.IO.File.CreateText(classMapSourceFileName));
512             CodeFormatter formatter(classMapFile);
513             Cm.Ast.SourceWriter sourceWriter(formatter);
514             classMapUnit.Accept(sourceWriter);
515             if (verbose)
516             {
517                 Console.Out() << "==> " << classMapSourceFileName << endl();
518             }
519         }
520         public inline nothrow const Uuid& ModuleId() const
521         {
522             return moduleId;
523         }
524         private int nextNfaStateId;
525         private int nextDfaStateId;
526         private int lexerStatementIndex;
527         private int classIndex;
528         private string fileName;
529         private List<NfaState*> nfaStates;
530         private List<DfaState*> dfaStates;
531         private List<Symbol*> symbols;
532         private List<Class*> canonicalClasses;
533         private List<Class*> partition;
534         private List<Cm.Ast.Node*> usingNodes;
535         private Map<ucharSymbol*> charSymbols;
536         private Map<RangeSymbol*> rangeSymbols;
537         private Any any;
538         private Char epsilon;
539         private Class* idStart;
540         private Class* idCont;
541         private ClassMap* classMap;
542         private Usings* usings;
543         private Tokens* tokens;
544         private Keywords* keywords;
545         private Expressions* expressions;
546         private Lexer* lexer;
547         private Parser* parser;
548         private Expression* currentExpression;
549         private ustring api;
550         private Uuid moduleId;
551     }
552     public class ClassLess
553     {
554         public bool operator()(const Class* leftconst Class* right) const
555         {
556             if (left->Ranges().Count() < right->Ranges().Count()) return false;
557             if (left->Ranges().Count() > right->Ranges().Count()) return false;
558             if (!left->Ranges().IsEmpty())
559             {
560                 Range leftRange = left->Ranges().Front();
561                 Range rightRange = right->Ranges().Front();
562                 return leftRange < rightRange;
563             }
564             return false;
565         }
566     }
567     public class ClassesEqual
568     {
569         public bool operator()(const Class* leftconst Class* right) const
570         {
571             return left->Ranges() == right->Ranges();
572         }
573     }
574 } // namespace soulcm.scmlg