1 using System;
2 using System.Collections;
3 using System.IO;
4 using System.Text;
5 using Cm.Ast;
6
7
8
9
10
11 namespace soulcm.scmlg
12 {
13 public abstract class Parser
14 {
15 public virtual ~Parser()
16 {
17 }
18 public abstract Nfa Parse(const ustring& expression, LexerContext* lexerContext, int line);
19 }
20 public abstract class Declaration
21 {
22 public Declaration(const ustring& name_) :
23 name(name_)
24 {
25 }
26 public virtual ~Declaration()
27 {
28 }
29 public const ustring& Name() const
30 {
31 return name;
32 }
33 public abstract void FillContext(LexerContext& lexerContext);
34 public abstract void Process(const string& root, bool verbose, LexerContext& lexerContext);
35 private ustring name;
36 }
37 public class ClassMap : Declaration
38 {
39 public ClassMap(const ustring& name_) :
40 base(name_)
41 {
42 }
43 public override void FillContext(LexerContext& lexerContext)
44 {
45 lexerContext.SetClassMap(this);
46 }
47 public override void Process(const string& root, bool verbose, LexerContext& lexerContext)
48 {
49 }
50 }
51 public class Usings : Declaration
52 {
53 public Usings() :
54 base(u"usings")
55 {
56 }
57 public const List<UniquePtr<Cm.Ast.Node>>& UsingNodes() const
58 {
59 return usingNodes;
60 }
61 public void AddMember(Cm.Ast.Node* usingNode)
62 {
63 usingNodes.Add(UniquePtr<Cm.Ast.Node>(usingNode));
64 }
65 public override void FillContext(LexerContext& lexerContext)
66 {
67 for (const UniquePtr<Cm.Ast.Node>& usingNode : usingNodes)
68 {
69 lexerContext.AddUsingNode(usingNode.Get());
70 }
71 }
72 public override void Process(const string& root, bool verbose, LexerContext& lexerContext)
73 {
74 }
75 private List<UniquePtr<Cm.Ast.Node>> usingNodes;
76 }
77 public class Token
78 {
79 public Token() :
80 name(), info()
81 {
82 }
83 public Token(const ustring& name_, const string& info_) :
84 name(name_), info(info_)
85 {
86 }
87 public ustring name;
88 public string info;
89 }
90 public class Tokens : Declaration
91 {
92 public Tokens(const ustring& name_) :
93 base(name_)
94 {
95 }
96 public void Add(const Token& token)
97 {
98 tokens.Add(token);
99 }
100 public override void FillContext(LexerContext& lexerContext)
101 {
102 lexerContext.SetTokens(this);
103 }
104 public override void Process(const string& root, bool verbose, LexerContext& lexerContext)
105 {
106 string tokenFileName = ToUtf8(Name()) + ".cm";
107 string tokenFilePath = GetFullPath(Path.Combine(root, tokenFileName));
108 Uuid moduleId = lexerContext.ModuleId();
109 Cm.Ast.CompileUnitNode compileUnit(System.Lex.Span(), moduleId, tokenFilePath);
110 compileUnit.GlobalNs()->AddMember(new Cm.Ast.NamespaceImportNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System")));
111 compileUnit.GlobalNs()->AddMember(new Cm.Ast.CommentNode(System.Lex.Span(), moduleId, u"this file has been automatically generated from \'" + ToUtf32(lexerContext.FileName()) + u"\' using soulcm lexer generator scmlg version " + ToUtf32(LexerGeneratorVersionStr())));
112 UniquePtr<Cm.Ast.NamespaceNode> ns(new Cm.Ast.NamespaceNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, Name())));
113 UniquePtr<Cm.Ast.ConstantNode> end(new Cm.Ast.ConstantNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"END"), new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, 0)));
114 ns->AddMember(end.Release());
115 Map<ustring, int> tokenIdMap;
116 int i = 1;
117 for (const Token& t : tokens)
118 {
119 tokenIdMap[t.name] = i;
120 UniquePtr<Cm.Ast.ConstantNode> token(new Cm.Ast.ConstantNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, t.name), new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, i++)));
121 ns->AddMember(token.Release());
122 }
123 UniquePtr<Cm.Ast.ClassNode> tokenMapClass(new Cm.Ast.ClassNode(System.Lex.Span(), moduleId, Specifiers.internal_, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"TokenMap"), null));
124 UniquePtr<Cm.Ast.StaticConstructorNode> staticConstructor(new Cm.Ast.StaticConstructorNode(System.Lex.Span(), moduleId, Specifiers.static_, null));
125 staticConstructor->SetClassId(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"TokenMap"));
126 staticConstructor->SetBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
127 UniquePtr<Cm.Ast.MemberInitializerNode> init(new Cm.Ast.MemberInitializerNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"instance")));
128 Cm.Ast.TemplateIdNode instanceType(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"UniquePtr")));
129 instanceType.AddTemplateArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"TokenMap"));
130 Cm.Ast.CloneContext cloneContext;
131 Cm.Ast.NewNode* newNode = new Cm.Ast.NewNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"TokenMap"));
132 init->AddArgument(newNode);
133 staticConstructor->AddInitializer(init.Release());
134 tokenMapClass->AddMember(staticConstructor.Release());
135 UniquePtr<Cm.Ast.MemberFunctionNode> instanceMemFun(new Cm.Ast.MemberFunctionNode(System.Lex.Span(), moduleId, Specifiers.public_ | Specifiers.static_, new Cm.Ast.LValueRefNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"TokenMap")), u"Instance", null));
136 UniquePtr<Cm.Ast.CompoundStatementNode> instanceBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
137 instanceBody->AddStatement(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.DerefNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"instance"))));
138 instanceMemFun->SetBody(instanceBody.Release());
139 tokenMapClass->AddMember(instanceMemFun.Release());
140 UniquePtr<Cm.Ast.TemplateIdNode> mapType(new Cm.Ast.TemplateIdNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Collections")), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Map"))));
141 mapType->AddTemplateArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"ustring"));
142 mapType->AddTemplateArgument(new Cm.Ast.IntNode(System.Lex.Span(), moduleId));
143 UniquePtr<Cm.Ast.TemplateIdNode> listType(new Cm.Ast.TemplateIdNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Collections")), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"List"))));
144 listType->AddTemplateArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"ustring"));
145 UniquePtr<Cm.Ast.MemberFunctionNode> getTokenIdMemFun(new Cm.Ast.MemberFunctionNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), u"GetTokenId", null));
146 getTokenIdMemFun->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.ConstNode(System.Lex.Span(), moduleId, new Cm.Ast.LValueRefNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"ustring"))), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenName")));
147 UniquePtr<Cm.Ast.CompoundStatementNode> getTokenIdBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
148 UniquePtr<Cm.Ast.DotNode> iteratorType(new Cm.Ast.DotNode(System.Lex.Span(), moduleId, mapType->Clone(cloneContext), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"ConstIterator")));
149 UniquePtr<Cm.Ast.ConstructionStatementNode> constructIt(new Cm.Ast.ConstructionStatementNode(System.Lex.Span(), moduleId, iteratorType.Release(), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"it")));
150 UniquePtr<Cm.Ast.InvokeNode> invokeCFind(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenIdMap"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"CFind"))));
151 invokeCFind->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenName"));
152 constructIt->AddArgument(invokeCFind.Release());
153 constructIt->SetAssignment();
154 getTokenIdBody->AddStatement(constructIt.Release());
155 UniquePtr<Cm.Ast.CompoundStatementNode> thenS(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
156 UniquePtr<Cm.Ast.ReturnStatementNode> returnIt(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.ArrowNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"it"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"second"))));
157 thenS->AddStatement(returnIt.Release());
158 UniquePtr<Cm.Ast.CompoundStatementNode> elseS(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
159 UniquePtr<Cm.Ast.ReturnStatementNode> returnMinusOne(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, -1)));
160 elseS->AddStatement(returnMinusOne.Release());
161 UniquePtr<Cm.Ast.IfStatementNode> stmt(new Cm.Ast.IfStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.NotEqualNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"it"), new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenIdMap"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"CEnd")))), thenS.Release(), elseS.Release()));
162 getTokenIdBody->AddStatement(stmt.Release());
163 getTokenIdMemFun->SetBody(getTokenIdBody.Release());
164 tokenMapClass->AddMember(getTokenIdMemFun.Release());
165 UniquePtr<Cm.Ast.MemberFunctionNode> getTokenNameMemFun(new Cm.Ast.MemberFunctionNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"ustring"), u"GetTokenName", null));
166 getTokenNameMemFun->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenId")));
167 UniquePtr<Cm.Ast.CompoundStatementNode> getTokenNameMemFunBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
168 Cm.Ast.ReturnStatementNode* getTokenNameStmt = new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IndexingNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenNameList"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenId")));
169 getTokenNameMemFunBody->AddStatement(getTokenNameStmt);
170 getTokenNameMemFun->SetBody(getTokenNameMemFunBody.Release());
171 tokenMapClass->AddMember(getTokenNameMemFun.Release());
172 UniquePtr<Cm.Ast.MemberFunctionNode> getTokenInfoMemFun(new Cm.Ast.MemberFunctionNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"ustring"), u"GetTokenInfo", null));
173 getTokenInfoMemFun->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenId")));
174 UniquePtr<Cm.Ast.CompoundStatementNode> getTokenInfoMemFunBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
175 Cm.Ast.ReturnStatementNode* getTokenInfoStmt = new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IndexingNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenInfoList"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenId")));
176 getTokenInfoMemFunBody->AddStatement(getTokenInfoStmt);
177 getTokenInfoMemFun->SetBody(getTokenInfoMemFunBody.Release());
178 tokenMapClass->AddMember(getTokenInfoMemFun.Release());
179 UniquePtr<Cm.Ast.ConstructorNode> ctor(new Cm.Ast.ConstructorNode(System.Lex.Span(), moduleId, Specifiers.private_, null));
180 ctor->SetClassId(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"TokenMap"));
181 UniquePtr<Cm.Ast.CompoundStatementNode> ctorBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
182 for (const Pair<ustring, int>& p : tokenIdMap)
183 {
184 UniquePtr<Cm.Ast.AssignmentStatementNode> stmt(new Cm.Ast.AssignmentStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IndexingNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenIdMap"), new Cm.Ast.UStringLiteralNode(System.Lex.Span(), moduleId, p.first)), new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, p.second)));
185 ctorBody->AddStatement(stmt.Release());
186 }
187 Cm.Ast.DotNode* addToTokenNameList = new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenNameList"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Add"));
188 Cm.Ast.InvokeNode* invokeAdd = new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, addToTokenNameList);
189 invokeAdd->AddArgument(new Cm.Ast.UStringLiteralNode(System.Lex.Span(), moduleId, u"END"));
190 Cm.Ast.ExpressionStatementNode* addExpr = new Cm.Ast.ExpressionStatementNode(System.Lex.Span(), moduleId, invokeAdd);
191 ctorBody->AddStatement(addExpr);
192 Cm.Ast.DotNode* addToTokenInfoList = new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenInfoList"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Add"));
193 Cm.Ast.InvokeNode* invokeAddTokenInfo = new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, addToTokenInfoList);
194 invokeAddTokenInfo->AddArgument(new Cm.Ast.UStringLiteralNode(System.Lex.Span(), moduleId, u"end of file"));
195 Cm.Ast.ExpressionStatementNode* addTokenInfoExpr = new Cm.Ast.ExpressionStatementNode(System.Lex.Span(), moduleId, invokeAddTokenInfo);
196 ctorBody->AddStatement(addTokenInfoExpr);
197 for (const Token& t : tokens)
198 {
199 Cm.Ast.DotNode* addToTokenNameList = new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenNameList"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Add"));
200 Cm.Ast.InvokeNode* invokeAdd = new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, addToTokenNameList);
201 invokeAdd->AddArgument(new Cm.Ast.UStringLiteralNode(System.Lex.Span(), moduleId, t.name));
202 Cm.Ast.ExpressionStatementNode* addExpr = new Cm.Ast.ExpressionStatementNode(System.Lex.Span(), moduleId, invokeAdd);
203 ctorBody->AddStatement(addExpr);
204 Cm.Ast.DotNode* addToTokenInfoList = new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenInfoList"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Add"));
205 Cm.Ast.InvokeNode* invokeAddTokenInfo = new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, addToTokenInfoList);
206 invokeAddTokenInfo->AddArgument(new Cm.Ast.UStringLiteralNode(System.Lex.Span(), moduleId, ToUtf32(t.info)));
207 Cm.Ast.ExpressionStatementNode* addTokenInfoExpr = new Cm.Ast.ExpressionStatementNode(System.Lex.Span(), moduleId, invokeAddTokenInfo);
208 ctorBody->AddStatement(addTokenInfoExpr);
209 }
210 ctor->SetBody(ctorBody.Release());
211 tokenMapClass->AddMember(ctor.Release());
212 UniquePtr<Cm.Ast.MemberVariableNode> instanceMemVar(new Cm.Ast.MemberVariableNode(System.Lex.Span(), moduleId, Specifiers.private_ | Specifiers.static_, instanceType.Clone(cloneContext), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"instance"), null));
213 tokenMapClass->AddMember(instanceMemVar.Release());
214 UniquePtr<Cm.Ast.MemberVariableNode> tokenIdMapMemVar(new Cm.Ast.MemberVariableNode(System.Lex.Span(), moduleId, Specifiers.private_, mapType->Clone(cloneContext), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenIdMap"), null));
215 tokenMapClass->AddMember(tokenIdMapMemVar.Release());
216 UniquePtr<Cm.Ast.MemberVariableNode> tokenNameListMemVar(new Cm.Ast.MemberVariableNode(System.Lex.Span(), moduleId, Specifiers.private_, listType->Clone(cloneContext), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenNameList"), null));
217 tokenMapClass->AddMember(tokenNameListMemVar.Release());
218 UniquePtr<Cm.Ast.MemberVariableNode> tokenInfoListMemVar(new Cm.Ast.MemberVariableNode(System.Lex.Span(), moduleId, Specifiers.private_, listType->Clone(cloneContext), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenInfoList"), null));
219 tokenMapClass->AddMember(tokenInfoListMemVar.Release());
220 ns->AddMember(tokenMapClass.Release());
221 UniquePtr<Cm.Ast.FunctionNode> getTokenIdFun(new Cm.Ast.MemberFunctionNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), u"GetTokenId", null));
222 getTokenIdFun->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.ConstNode(System.Lex.Span(), moduleId, new Cm.Ast.LValueRefNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"ustring"))), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenName")));
223 UniquePtr<Cm.Ast.CompoundStatementNode> getTokenIdFunBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
224 UniquePtr<Cm.Ast.InvokeNode> invokeGetTokenIdMemFun(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"TokenMap"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Instance"))), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"GetTokenId"))));
225 invokeGetTokenIdMemFun->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenName"));
226 UniquePtr<Cm.Ast.ReturnStatementNode> returnTokenId(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, invokeGetTokenIdMemFun.Release()));
227 getTokenIdFunBody->AddStatement(returnTokenId.Release());
228 getTokenIdFun->SetBody(getTokenIdFunBody.Release());
229 ns->AddMember(getTokenIdFun.Release());
230 UniquePtr<Cm.Ast.FunctionNode> getTokenNameFun(new Cm.Ast.FunctionNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"ustring"), u"GetTokenName", null));
231 getTokenNameFun->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenId")));
232 UniquePtr<Cm.Ast.CompoundStatementNode> getTokenNameFunBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
233 UniquePtr<Cm.Ast.InvokeNode> invokeGetTokenNameMemFun(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"TokenMap"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Instance"))), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"GetTokenName"))));
234 invokeGetTokenNameMemFun->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenId"));
235 UniquePtr<Cm.Ast.ReturnStatementNode> returnTokenName(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, invokeGetTokenNameMemFun.Release()));
236 getTokenNameFunBody->AddStatement(returnTokenName.Release());
237 getTokenNameFun->SetBody(getTokenNameFunBody.Release());
238 ns->AddMember(getTokenNameFun.Release());
239 UniquePtr<Cm.Ast.FunctionNode> getTokenInfoFun(new Cm.Ast.FunctionNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"ustring"), u"GetTokenInfo", null));
240 getTokenInfoFun->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenId")));
241 UniquePtr<Cm.Ast.CompoundStatementNode> getTokenInfoFunBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
242 UniquePtr<Cm.Ast.InvokeNode> invokeGetTokenInfoMemFun(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"TokenMap"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Instance"))), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"GetTokenInfo"))));
243 invokeGetTokenInfoMemFun->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenId"));
244 UniquePtr<Cm.Ast.ReturnStatementNode> returnTokenInfo(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, invokeGetTokenInfoMemFun.Release()));
245 getTokenInfoFunBody->AddStatement(returnTokenInfo.Release());
246 getTokenInfoFun->SetBody(getTokenInfoFunBody.Release());
247 ns->AddMember(getTokenInfoFun.Release());
248 compileUnit.GlobalNs()->AddMember(ns.Release());
249 System.IO.StreamWriter tokenFile(System.IO.File.CreateText(tokenFilePath));
250 CodeFormatter formatter(tokenFile);
251 Cm.Ast.SourceWriter writer(formatter);
252 compileUnit.Accept(writer);
253 if (verbose)
254 {
255 Console.Out() << "==> " << tokenFilePath << endl();
256 }
257 }
258 private List<Token> tokens;
259 }
260 public class Keyword
261 {
262 public Keyword(const ustring& kw_, const ustring& token_) :
263 kw(kw_), token(token_)
264 {
265 }
266 public ustring kw;
267 public ustring token;
268 }
269 public class Keywords : Declaration
270 {
271 public Keywords(const ustring& name_) :
272 base(name_)
273 {
274 }
275 public void Add(Keyword* keyword)
276 {
277 keywords.Add(UniquePtr<Keyword>(keyword));
278 }
279 public override void FillContext(LexerContext& lexerContext)
280 {
281 lexerContext.SetKeywords(this);
282 }
283 public override void Process(const string& root, bool verbose, LexerContext& lexerContext)
284 {
285 string keywordFileName = ToUtf8(Name()) + ".cm";
286 string keywordFilePath = GetFullPath(Path.Combine(root, keywordFileName));
287 Uuid moduleId = lexerContext.ModuleId();
288 Cm.Ast.CompileUnitNode compileUnit(System.Lex.Span(), moduleId, keywordFilePath);
289 compileUnit.GlobalNs()->AddMember(new Cm.Ast.NamespaceImportNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System")));
290 compileUnit.GlobalNs()->AddMember(new Cm.Ast.CommentNode(System.Lex.Span(), moduleId, u"this file has been automatically generated from \'" + ToUtf32(lexerContext.FileName()) + u"\' using soulcm lexer generator scmlg version " + ToUtf32(LexerGeneratorVersionStr())));
291 UniquePtr<Cm.Ast.NamespaceNode> ns(new Cm.Ast.NamespaceNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, Name())));
292 UniquePtr<Cm.Ast.ClassNode> keywordsClass(new Cm.Ast.ClassNode(System.Lex.Span(), moduleId, Specifiers.internal_, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Keywords"), null));
293 UniquePtr<Cm.Ast.StaticConstructorNode> staticConstructor(new Cm.Ast.StaticConstructorNode(System.Lex.Span(), moduleId, Specifiers.static_, null));
294 staticConstructor->SetClassId(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Keywords"));
295 staticConstructor->SetBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
296 UniquePtr<Cm.Ast.MemberInitializerNode> init(new Cm.Ast.MemberInitializerNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"instance")));
297 Cm.Ast.TemplateIdNode instanceType(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"UniquePtr")));
298 instanceType.AddTemplateArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Keywords"));
299 Cm.Ast.CloneContext cloneContext;
300 Cm.Ast.NewNode* newNode = new Cm.Ast.NewNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Keywords"));
301 init->AddArgument(newNode);
302 staticConstructor->AddInitializer(init.Release());
303 keywordsClass->AddMember(staticConstructor.Release());
304 UniquePtr<Cm.Ast.MemberFunctionNode> instanceMemFun(new Cm.Ast.MemberFunctionNode(System.Lex.Span(), moduleId, Specifiers.public_ | Specifiers.static_, new Cm.Ast.LValueRefNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Keywords")), u"Instance", null));
305 UniquePtr<Cm.Ast.CompoundStatementNode> instanceBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
306 instanceBody->AddStatement(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.DerefNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"instance"))));
307 instanceMemFun->SetBody(instanceBody.Release());
308 keywordsClass->AddMember(instanceMemFun.Release());
309 Cm.Ast.DotNode keywordType(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Lex")), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Keyword"));
310 Cm.Ast.TemplateIdNode uniquePtrKeywordMapType(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"UniquePtr")));
311 Cm.Ast.DotNode keywordMapType(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Lex")), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"KeywordMap"));
312 uniquePtrKeywordMapType.AddTemplateArgument(keywordMapType.Clone(cloneContext));
313 UniquePtr<Cm.Ast.MemberFunctionNode> getkeywordMapMemFun(new Cm.Ast.MemberFunctionNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.PointerNode(System.Lex.Span(), moduleId, keywordMapType.Clone(cloneContext)), u"GetKeywordMap", null));
314 UniquePtr<Cm.Ast.CompoundStatementNode> getkeywordMapMemFunBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
315 UniquePtr<Cm.Ast.InvokeNode> invokeGetKeywordMap(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"keywordMap"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Get"))));
316 UniquePtr<Cm.Ast.ReturnStatementNode> getKeywordMapStmt(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, invokeGetKeywordMap.Release()));
317 getkeywordMapMemFunBody->AddStatement(getKeywordMapStmt.Release());
318 getkeywordMapMemFun->SetBody(getkeywordMapMemFunBody.Release());
319 keywordsClass->AddMember(getkeywordMapMemFun.Release());
320 UniquePtr<Cm.Ast.ConstructorNode> ctor(new Cm.Ast.ConstructorNode(System.Lex.Span(), moduleId, Specifiers.private_, null));
321 ctor->SetClassId(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Keywords"));
322 UniquePtr<Cm.Ast.CompoundStatementNode> ctorBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
323 int index = 0;
324 for (const UniquePtr<Keyword>& k : keywords)
325 {
326 UniquePtr<Cm.Ast.ConstructionStatementNode> constructKeyword(new Cm.Ast.ConstructionStatementNode(System.Lex.Span(), moduleId, keywordType.Clone(cloneContext), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"keyword" + ToUtf32(ToString(index)))));
327 constructKeyword->AddArgument(new Cm.Ast.UStringLiteralNode(System.Lex.Span(), moduleId, k->kw));
328 constructKeyword->AddArgument(new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, lexerContext.GetTokens()->Name()), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, k->token)));
329 ctorBody->AddStatement(constructKeyword.Release());
330 UniquePtr<Cm.Ast.InvokeNode> invokeAdd(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"keywordList"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Add"))));
331 invokeAdd->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"keyword" + ToUtf32(ToString(index))));
332 UniquePtr<Cm.Ast.ExpressionStatementNode> addToKeywordList(new Cm.Ast.ExpressionStatementNode(System.Lex.Span(), moduleId, invokeAdd.Release()));
333 ctorBody->AddStatement(addToKeywordList.Release());
334 ++index;
335 }
336 UniquePtr<Cm.Ast.ConstructionStatementNode> constructNullKeyword(new Cm.Ast.ConstructionStatementNode(System.Lex.Span(), moduleId, keywordType.Clone(cloneContext), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"nullKeyword")));
337 constructNullKeyword->AddArgument(new Cm.Ast.NullLiteralNode(System.Lex.Span(), moduleId));
338 constructNullKeyword->AddArgument(new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, -1));
339 ctorBody->AddStatement(constructNullKeyword.Release());
340 UniquePtr<Cm.Ast.InvokeNode> invokeAdd(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"keywordList"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Add"))));
341 invokeAdd->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"nullKeyword"));
342 UniquePtr<Cm.Ast.ExpressionStatementNode> addToKeywordList(new Cm.Ast.ExpressionStatementNode(System.Lex.Span(), moduleId, invokeAdd.Release()));
343 ctorBody->AddStatement(addToKeywordList.Release());
344 UniquePtr<Cm.Ast.InvokeNode> invokeReset(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"keywordMap"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Reset"))));
345 UniquePtr<Cm.Ast.NewNode> newKeywordMap(new Cm.Ast.NewNode(System.Lex.Span(), moduleId, keywordMapType.Clone(cloneContext)));
346 UniquePtr<Cm.Ast.InvokeNode> invokeCBegin(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"keywordList"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"CBegin"))));
347 UniquePtr<Cm.Ast.InvokeNode> invokePtr(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, invokeCBegin.Release(), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Ptr"))));
348 newKeywordMap->AddArgument(invokePtr.Release());
349 invokeReset->AddArgument(newKeywordMap.Release());
350 UniquePtr<Cm.Ast.ExpressionStatementNode> resetKeywordMap(new Cm.Ast.ExpressionStatementNode(System.Lex.Span(), moduleId, invokeReset.Release()));
351 ctorBody->AddStatement(resetKeywordMap.Release());
352 ctor->SetBody(ctorBody.Release());
353 keywordsClass->AddMember(ctor.Release());
354 UniquePtr<Cm.Ast.MemberVariableNode> instanceMemVar(new Cm.Ast.MemberVariableNode(System.Lex.Span(), moduleId, Specifiers.private_ | Specifiers.static_, instanceType.Clone(cloneContext), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"instance"), null));
355 keywordsClass->AddMember(instanceMemVar.Release());
356 Cm.Ast.TemplateIdNode keywordListType(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Collections")), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"List")));
357 keywordListType.AddTemplateArgument(keywordType.Clone(cloneContext));
358 UniquePtr<Cm.Ast.MemberVariableNode> keywordListMemVar(new Cm.Ast.MemberVariableNode(System.Lex.Span(), moduleId, Specifiers.private_, keywordListType.Clone(cloneContext), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"keywordList"), null));
359 keywordsClass->AddMember(keywordListMemVar.Release());
360 UniquePtr<Cm.Ast.MemberVariableNode> keywordMapMemVar(new Cm.Ast.MemberVariableNode(System.Lex.Span(), moduleId, Specifiers.private_, uniquePtrKeywordMapType.Clone(cloneContext), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"keywordMap"), null));
361 keywordsClass->AddMember(keywordMapMemVar.Release());
362 ns->AddMember(keywordsClass.Release());
363 UniquePtr<Cm.Ast.FunctionNode> getKeywordMapFun(new Cm.Ast.FunctionNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.PointerNode(System.Lex.Span(), moduleId, keywordMapType.Clone(cloneContext)), u"GetKeywordMap", null));
364 UniquePtr<Cm.Ast.CompoundStatementNode> getKeywordMapFunBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
365 UniquePtr<Cm.Ast.InvokeNode> invokeGetKeywordMapMemFun(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Keywords"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Instance"))), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"GetKeywordMap"))));
366 UniquePtr<Cm.Ast.ReturnStatementNode> returnKeywordMap(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, invokeGetKeywordMapMemFun.Release()));
367 getKeywordMapFunBody->AddStatement(returnKeywordMap.Release());
368 getKeywordMapFun->SetBody(getKeywordMapFunBody.Release());
369 ns->AddMember(getKeywordMapFun.Release());
370 compileUnit.GlobalNs()->AddMember(ns.Release());
371 System.IO.StreamWriter keywordFile(System.IO.File.CreateText(keywordFilePath));
372 CodeFormatter formatter(keywordFile);
373 Cm.Ast.SourceWriter writer(formatter);
374 compileUnit.Accept(writer);
375 if (verbose)
376 {
377 Console.Out() << "==> " << keywordFilePath << endl();
378 }
379 }
380 private List<UniquePtr<Keyword>> keywords;
381 }
382 public class Expression
383 {
384 public Expression(int index_, const ustring& id_, const ustring& value_, int line_) :
385 index(index_), id(id_), value(value_), line(line_)
386 {
387 }
388 public int Index() const
389 {
390 return index;
391 }
392 public const ustring& Id() const
393 {
394 return id;
395 }
396 public const ustring& Value() const
397 {
398 return value;
399 }
400 public int Line() const
401 {
402 return line;
403 }
404 private int index;
405 private ustring id;
406 private ustring value;
407 private int line;
408 }
409 public class Expressions : Declaration
410 {
411 public Expressions() :
412 base(u"expressions")
413 {
414 }
415 public void Add(Expression* expression)
416 {
417 expressions.Add(UniquePtr<Expression>(expression));
418 exprMap[expression->Id()] = expression->Index();
419 }
420 public Expression* Get(const ustring& id) const
421 {
422 Map<ustring, int>.ConstIterator it = exprMap.CFind(id);
423 if (it != exprMap.CEnd())
424 {
425 int index = it->second;
426 return expressions[index].Get();
427 }
428 else
429 {
430 throw Exception("expression \'" + ToUtf8(id) + "\' not found");
431 }
432 }
433 public override void FillContext(LexerContext& lexerContext)
434 {
435 lexerContext.SetExpressions(this);
436 }
437 public override void Process(const string& root, bool verbose, LexerContext& lexerContext)
438 {
439 }
440 private List<UniquePtr<Expression>> expressions;
441 private Map<ustring, int> exprMap;
442 }
443 public class Variable
444 {
445 public Variable(Cm.Ast.Node* type_, const ustring& name_) :
446 type(type_), name(name_)
447 {
448 }
449 public Cm.Ast.Node* GetType() const
450 {
451 return type.Get();
452 }
453 public const ustring& Name() const
454 {
455 return name;
456 }
457 private UniquePtr<Cm.Ast.Node> type;
458 private ustring name;
459 }
460 public class LexerStatement
461 {
462 public LexerStatement(const ustring& expr_, Cm.Ast.CompoundStatementNode* stmt_, int action_, int line_) :
463 index(-1), expr(expr_), stmt(stmt_), retract(true), action(action_), line(line_)
464 {
465 }
466 public void SetIndex(int index_)
467 {
468 index = index_;
469 }
470 public int Index() const
471 {
472 return index;
473 }
474 public const Nfa& GetNfa() const
475 {
476 return nfa;
477 }
478 public Cm.Ast.CompoundStatementNode* Code() const
479 {
480 return stmt.Get();
481 }
482 public bool Retract() const
483 {
484 return retract;
485 }
486 public int Action() const
487 {
488 return action;
489 }
490 public int Line() const
491 {
492 return line;
493 }
494 public void Process(LexerContext& lexerContext)
495 {
496 nfa = lexerContext.GetParser()->Parse(expr, &lexerContext, line);
497 nfa.End()->SetStatementIndex(index);
498 }
499 private int index;
500 private ustring expr;
501 private Nfa nfa;
502 private UniquePtr<Cm.Ast.CompoundStatementNode> stmt;
503 private bool retract;
504 private int action;
505 private int line;
506 }
507 public class Action
508 {
509 public Action(int id_, Cm.Ast.CompoundStatementNode* stmt_) :
510 id(id_), stmt(stmt_)
511 {
512 }
513 public int Id() const
514 {
515 return id;
516 }
517 public Cm.Ast.CompoundStatementNode* Code() const
518 {
519 return stmt.Get();
520 }
521 private int id;
522 private UniquePtr<Cm.Ast.CompoundStatementNode> stmt;
523 }
524 public class Actions : Declaration
525 {
526 public Actions() :
527 base(u"actions")
528 {
529 }
530 public void Add(Action* action)
531 {
532 actions.Add(UniquePtr<Action>(action));
533 actionMap[action->Id()] = action;
534 }
535 public Action* Get(int id) const
536 {
537 Map<int, Action*>.ConstIterator it = actionMap.CFind(id);
538 if (it != actionMap.CEnd())
539 {
540 return it->second;
541 }
542 else
543 {
544 return null;
545 }
546 }
547 public override void FillContext(LexerContext& lexerContext)
548 {
549 }
550 public override void Process(const string& root, bool verbose, LexerContext& lexerContext)
551 {
552 }
553 private List<UniquePtr<Action>> actions;
554 private Map<int, Action*> actionMap;
555 }
556 public class Lexer : Declaration
557 {
558 public Lexer(const ustring& api_, const ustring& name_) :
559 base(name_), api(api_)
560 {
561 }
562 public void AddStatement(LexerStatement* stmt)
563 {
564 stmt->SetIndex(cast<int>(statements.Count()));
565 statements.Add(UniquePtr<LexerStatement>(stmt));
566 }
567 public void AddVariable(Variable* variable)
568 {
569 variables.Add(UniquePtr<Variable>(variable));
570 }
571 public void AddAction(Action* action)
572 {
573 actions.Add(action);
574 }
575 public void MakeMasterNfa(LexerContext& lexerContext)
576 {
577 NfaState* start = lexerContext.MakeNfaState();
578 masterNfa.SetStart(start);
579 for (const UniquePtr<LexerStatement>& statement : statements)
580 {
581 start->AddEdge(NfaEdge(lexerContext.MakeEpsilon(), statement->GetNfa().Start()));
582 }
583 }
584 public void MakeDfa(LexerContext& lexerContext)
585 {
586 dfa = Compile(lexerContext, masterNfa);
587 }
588 public void WriteAutomaton(const string& root, bool verbose, LexerContext& lexerContext)
589 {
590 Cm.Ast.CloneContext cloneContext;
591 string lexerFileName = ToUtf8(Name()) + ".cm";
592 string lexerFilePath = GetFullPath(Path.Combine(root, lexerFileName));
593 Uuid moduleId = lexerContext.ModuleId();
594 Cm.Ast.CompileUnitNode compileUnit(System.Lex.Span(), moduleId, lexerFilePath);
595 compileUnit.GlobalNs()->AddMember(new Cm.Ast.NamespaceImportNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System")));
596 compileUnit.GlobalNs()->AddMember(new Cm.Ast.NamespaceImportNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System.Lex")));
597 compileUnit.GlobalNs()->AddMember(new Cm.Ast.NamespaceImportNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, lexerContext.GetTokens()->Name())));
598 for (Cm.Ast.Node* usingNode : lexerContext.GetUsingNodes())
599 {
600 compileUnit.GlobalNs()->AddMember(usingNode->Clone(cloneContext));
601 }
602 compileUnit.GlobalNs()->AddMember(new Cm.Ast.CommentNode(System.Lex.Span(), moduleId, u"this file has been automatically generated from \'" + ToUtf32(lexerContext.FileName()) + u"\' using soulcm lexer generator scmlg version " + ToUtf32(LexerGeneratorVersionStr())));
603 UniquePtr<Cm.Ast.ClassNode> classNode(new Cm.Ast.ClassNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, Name()), null));
604 classNode->AddBaseClassOrInterface(new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Lex")), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Lexer")));
605 UniquePtr<Cm.Ast.ConstructorNode> contentCtor(new Cm.Ast.ConstructorNode(System.Lex.Span(), moduleId, Specifiers.public_, null));
606 contentCtor->SetClassId(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, Name()));
607 contentCtor->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.ConstNode(System.Lex.Span(), moduleId, new Cm.Ast.LValueRefNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"ustring"))), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"content_")));
608 contentCtor->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.ConstNode(System.Lex.Span(), moduleId, new Cm.Ast.LValueRefNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"string"))), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"fileName_")));
609 contentCtor->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"fileIndex_")));
610 Cm.Ast.BaseInitializerNode* baseInitializer = new Cm.Ast.BaseInitializerNode(System.Lex.Span(), moduleId);
611 baseInitializer->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"content_"));
612 baseInitializer->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"fileName_"));
613 baseInitializer->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"fileIndex_"));
614 contentCtor->AddInitializer(baseInitializer);
615 for (const UniquePtr<Variable>& variable : variables)
616 {
617 Cm.Ast.MemberInitializerNode* memInit = new Cm.Ast.MemberInitializerNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, variable->Name()));
618 contentCtor->AddInitializer(memInit);
619 }
620 UniquePtr<Cm.Ast.CompoundStatementNode> contentCtorBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
621 if ((lexerContext.GetKeywords() != null))
622 {
623 UniquePtr<Cm.Ast.InvokeNode> invokeSetKeywordMap(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"SetKeywordMap")));
624 invokeSetKeywordMap->AddArgument(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, lexerContext.GetKeywords()->Name()), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"GetKeywordMap"))));
625 UniquePtr<Cm.Ast.ExpressionStatementNode> setKeywordMapStmt(new Cm.Ast.ExpressionStatementNode(System.Lex.Span(), moduleId, invokeSetKeywordMap.Release()));
626 contentCtorBody->AddStatement(setKeywordMapStmt.Release());
627 }
628 UniquePtr<Cm.Ast.InvokeNode> invokeInitClassMap(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId,
629 new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, lexerContext.GetClassMap()->Name()), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Init"))));
630 UniquePtr<Cm.Ast.ExpressionStatementNode> initClassMapStmt(new Cm.Ast.ExpressionStatementNode(System.Lex.Span(), moduleId, invokeInitClassMap.Release()));
631 contentCtorBody->AddStatement(initClassMapStmt.Release());
632 contentCtor->SetBody(contentCtorBody.Release());
633 classNode->AddMember(contentCtor.Release());
634 UniquePtr<Cm.Ast.ConstructorNode> startCtor(new Cm.Ast.ConstructorNode(System.Lex.Span(), moduleId, Specifiers.public_, null));
635 startCtor->SetClassId(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, Name()));
636 startCtor->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.ConstNode(System.Lex.Span(), moduleId, new Cm.Ast.PointerNode(System.Lex.Span(), moduleId, new Cm.Ast.UCharNode(System.Lex.Span(), moduleId))), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"start_")));
637 startCtor->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.ConstNode(System.Lex.Span(), moduleId, new Cm.Ast.PointerNode(System.Lex.Span(), moduleId, new Cm.Ast.UCharNode(System.Lex.Span(), moduleId))), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"end_")));
638 startCtor->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.ConstNode(System.Lex.Span(), moduleId, new Cm.Ast.LValueRefNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"string"))), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"fileName_")));
639 startCtor->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"fileIndex_")));
640 Cm.Ast.BaseInitializerNode* baseInit = new Cm.Ast.BaseInitializerNode(System.Lex.Span(), moduleId);
641 baseInit->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"start_"));
642 baseInit->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"end_"));
643 baseInit->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"fileName_"));
644 baseInit->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"fileIndex_"));
645 startCtor->AddInitializer(baseInit);
646 for (const UniquePtr<Variable>& variable : variables)
647 {
648 Cm.Ast.MemberInitializerNode* memInit = new Cm.Ast.MemberInitializerNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, variable->Name()));
649 startCtor->AddInitializer(memInit);
650 }
651 UniquePtr<Cm.Ast.CompoundStatementNode> startCtorBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
652 if ((lexerContext.GetKeywords() != null))
653 {
654 UniquePtr<Cm.Ast.InvokeNode> invokeSetKeywordMap2(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"SetKeywordMap")));
655 invokeSetKeywordMap2->AddArgument(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, lexerContext.GetKeywords()->Name()), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"GetKeywordMap"))));
656 UniquePtr<Cm.Ast.ExpressionStatementNode> setKeywordMapStmt2(new Cm.Ast.ExpressionStatementNode(System.Lex.Span(), moduleId, invokeSetKeywordMap2.Release()));
657 startCtorBody->AddStatement(setKeywordMapStmt2.Release());
658 }
659 UniquePtr<Cm.Ast.InvokeNode> invokeInitClassMap2(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId,
660 new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, lexerContext.GetClassMap()->Name()), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Init"))));
661 UniquePtr<Cm.Ast.ExpressionStatementNode> initClassMapStmt2(new Cm.Ast.ExpressionStatementNode(System.Lex.Span(), moduleId, invokeInitClassMap2.Release()));
662 startCtorBody->AddStatement(initClassMapStmt2.Release());
663 startCtor->SetBody(startCtorBody.Release());
664 classNode->AddMember(startCtor.Release());
665 UniquePtr<Cm.Ast.MemberFunctionNode> nextStateMemFun(new Cm.Ast.MemberFunctionNode(System.Lex.Span(), moduleId, Specifiers.public_ | Specifiers.override_, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), u"NextState", null));
666 nextStateMemFun->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"state")));
667 nextStateMemFun->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.UCharNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"c")));
668 UniquePtr<Cm.Ast.CompoundStatementNode> nextStateMemFunBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
669
670 string classMapName = "ClassMap";
671 if ((lexerContext.GetClassMap() != null))
672 {
673 classMapName = ToUtf8(lexerContext.GetClassMap()->Name());
674 }
675 UniquePtr<Cm.Ast.ConstructionStatementNode> constructI(new Cm.Ast.ConstructionStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"i")));
676 UniquePtr<Cm.Ast.InvokeNode> invokeGetClass(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, ToUtf32(classMapName)), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"GetClass"))));
677 invokeGetClass->AddArgument(new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"c"));
678 constructI->SetAssignment();
679 constructI->AddArgument(invokeGetClass.Release());
680 nextStateMemFunBody->AddStatement(constructI.Release());
681 UniquePtr<Cm.Ast.SwitchStatementNode> switchStmt(new Cm.Ast.SwitchStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"state")));
682 for (DfaState* state : dfa.States())
683 {
684 UniquePtr<Cm.Ast.CaseStatementNode> caseStmt(new Cm.Ast.CaseStatementNode(System.Lex.Span(), moduleId));
685 caseStmt->AddCaseExpr(new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, state->Id()));
686 UniquePtr<Cm.Ast.CompoundStatementNode> caseBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
687 if (state->Accept())
688 {
689 UniquePtr<Cm.Ast.ConstructionStatementNode> constructPrevMatch(new Cm.Ast.ConstructionStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"System"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Lex")), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Lexeme")), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"prevMatch")));
690 constructPrevMatch->SetAssignment();
691 constructPrevMatch->AddArgument(new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"token"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"match")));
692 UniquePtr<Cm.Ast.AssignmentStatementNode> assignmentStmt(new Cm.Ast.AssignmentStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"token"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"match")), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"lexeme")));
693 caseBody->AddStatement(constructPrevMatch.Release());
694 caseBody->AddStatement(assignmentStmt.Release());
695 UniquePtr<Cm.Ast.ConstructionStatementNode> constructTokenId(new Cm.Ast.ConstructionStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenId")));
696 constructTokenId->SetAssignment();
697 UniquePtr<Cm.Ast.InvokeNode> invokeGetTokenId(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"GetTokenId")));
698 invokeGetTokenId->AddArgument(new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, state->StatementIndex()));
699 constructTokenId->AddArgument(invokeGetTokenId.Release());
700 caseBody->AddStatement(constructTokenId.Release());
701 UniquePtr<Cm.Ast.CompoundStatementNode> thenS(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
702 UniquePtr<Cm.Ast.AssignmentStatementNode> assignTokenIdStmt(new Cm.Ast.AssignmentStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"token"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"id")), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"CONTINUE_TOKEN")));
703 thenS->AddStatement(assignTokenIdStmt.Release());
704 thenS->AddStatement(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, -1)));
705 UniquePtr<Cm.Ast.CompoundStatementNode> elseS(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
706 UniquePtr<Cm.Ast.CompoundStatementNode> thenS2(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
707 UniquePtr<Cm.Ast.AssignmentStatementNode> assignStmt2(new Cm.Ast.AssignmentStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"token"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"id")), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenId")));
708 thenS2->AddStatement(assignStmt2.Release());
709 UniquePtr<Cm.Ast.CompoundStatementNode> elseS2(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
710 elseS2->AddStatement(new Cm.Ast.AssignmentStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.DotNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"token"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"match")), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"prevMatch")));
711 UniquePtr<Cm.Ast.IfStatementNode> ifStmt2(new Cm.Ast.IfStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.NotEqualNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenId"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"INVALID_TOKEN")), thenS2.Release(), elseS2.Release()));
712 elseS->AddStatement(ifStmt2.Release());
713 UniquePtr<Cm.Ast.IfStatementNode> ifStmt(new Cm.Ast.IfStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.EqualNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"tokenId"), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"CONTINUE_TOKEN")), thenS.Release(), elseS.Release()));
714 caseBody->AddStatement(ifStmt.Release());
715 }
716 Map<int, Set<int>> m;
717 for (Class* cls : lexerContext.Partition())
718 {
719 DfaState* next = state->Next(cls->Index());
720 if (next != null)
721 {
722 m[next->Id()].Insert(cls->Index());
723 }
724 }
725 if (m.IsEmpty())
726 {
727 caseBody->AddStatement(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, -1)));
728 }
729 else
730 {
731 UniquePtr<Cm.Ast.SwitchStatementNode> switchStmt(new Cm.Ast.SwitchStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"i")));
732 for (const Pair<int, Set<int>>& p : m)
733 {
734 int n = p.first;
735 const Set<int>& s = p.second;
736 UniquePtr<Cm.Ast.CaseStatementNode> caseS(new Cm.Ast.CaseStatementNode(System.Lex.Span(), moduleId));
737 for (int k : s)
738 {
739 caseS->AddCaseExpr(new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, k));
740 }
741 UniquePtr<Cm.Ast.CompoundStatementNode> caseBlock(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
742 caseBlock->AddStatement(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, n)));
743 caseS->AddStatement(caseBlock.Release());
744 switchStmt->AddCase(caseS.Release());
745 UniquePtr<Cm.Ast.DefaultStatementNode> defaultS(new Cm.Ast.DefaultStatementNode(System.Lex.Span(), moduleId));
746 UniquePtr<Cm.Ast.CompoundStatementNode> defaultBlock(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
747 defaultBlock->AddStatement(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, -1)));
748 defaultS->AddStatement(defaultBlock.Release());
749 switchStmt->SetDefault(defaultS.Release());
750 }
751 caseBody->AddStatement(switchStmt.Release());
752 caseBody->AddStatement(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, -1)));
753 }
754 caseStmt->AddStatement(caseBody.Release());
755 switchStmt->AddCase(caseStmt.Release());
756 }
757 nextStateMemFunBody->AddStatement(switchStmt.Release());
758 nextStateMemFunBody->AddStatement(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, -1)));
759 nextStateMemFun->SetBody(nextStateMemFunBody.Release());
760 classNode->AddMember(nextStateMemFun.Release());
761 UniquePtr<Cm.Ast.MemberFunctionNode> getTokenIdMemFun(new Cm.Ast.MemberFunctionNode(System.Lex.Span(), moduleId, Specifiers.private_, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), u"GetTokenId", null));
762 getTokenIdMemFun->AddParameter(new Cm.Ast.ParameterNode(System.Lex.Span(), moduleId, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"statementIndex")));
763 UniquePtr<Cm.Ast.CompoundStatementNode> getTokenIdMemFunBody(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
764 UniquePtr<Cm.Ast.SwitchStatementNode> switchStmt2(new Cm.Ast.SwitchStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"statementIndex")));
765 for (const UniquePtr<LexerStatement>& statement : statements)
766 {
767 UniquePtr<Cm.Ast.CaseStatementNode> caseS(new Cm.Ast.CaseStatementNode(System.Lex.Span(), moduleId));
768 caseS->AddCaseExpr(new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, statement->Index()));
769 UniquePtr<Cm.Ast.CompoundStatementNode> caseBlock(new Cm.Ast.CompoundStatementNode(System.Lex.Span(), moduleId));
770 if (statement->Retract())
771 {
772 UniquePtr<Cm.Ast.InvokeNode> invokeRetract(new Cm.Ast.InvokeNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Retract")));
773 UniquePtr<Cm.Ast.ExpressionStatementNode> retractStmt(new Cm.Ast.ExpressionStatementNode(System.Lex.Span(), moduleId, invokeRetract.Release()));
774 caseBlock->AddStatement(retractStmt.Release());
775 }
776 if (statement->Action() != -1)
777 {
778 Action* action = actions.Get(statement->Action());
779 if (action != null)
780 {
781 int n = action->Code()->Statements().Count();
782 for (int i = 0; i < n; ++i;)
783 {
784 Cm.Ast.StatementNode* stmt = action->Code()->Statements()[i];
785 caseBlock->AddStatement(cast<Cm.Ast.StatementNode*>(stmt->Clone(cloneContext)));
786 }
787 }
788 else
789 {
790 throw Exception("action " + ToString(statement->Action()) + " not found");
791 }
792 }
793 int n = statement->Code()->Statements().Count();
794 for (int i = 0; i < n; ++i;)
795 {
796 caseBlock->AddStatement(cast<Cm.Ast.StatementNode*>(statement->Code()->Statements()[i]->Clone(cloneContext)));
797 }
798 caseBlock->AddStatement(new Cm.Ast.BreakStatementNode(System.Lex.Span(), moduleId));
799 caseS->AddStatement(caseBlock.Release());
800 switchStmt2->AddCase(caseS.Release());
801 }
802 getTokenIdMemFunBody->AddStatement(switchStmt2.Release());
803 getTokenIdMemFunBody->AddStatement(new Cm.Ast.ReturnStatementNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"CONTINUE_TOKEN")));
804 getTokenIdMemFun->SetBody(getTokenIdMemFunBody.Release());
805 classNode->AddMember(getTokenIdMemFun.Release());
806 for (const UniquePtr<Variable>& variable : variables)
807 {
808 Cm.Ast.MemberVariableNode* var = new Cm.Ast.MemberVariableNode(System.Lex.Span(), moduleId, Specifiers.public_, variable->GetType()->Clone(cloneContext), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, variable->Name()), null);
809 classNode->AddMember(var);
810 }
811 compileUnit.GlobalNs()->AddMember(classNode.Release());
812 System.IO.StreamWriter lexerFile(System.IO.File.CreateText(lexerFilePath));
813 CodeFormatter formatter(lexerFile);
814 Cm.Ast.SourceWriter writer(formatter);
815 compileUnit.Accept(writer);
816 if (verbose)
817 {
818 Console.Out() << "==> " << lexerFilePath << endl();
819 }
820 }
821 public override void FillContext(LexerContext& lexerContext)
822 {
823 lexerContext.SetApi(api);
824 lexerContext.SetLexer(this);
825 }
826 public override void Process(const string& root, bool verbose, LexerContext& lexerContext)
827 {
828 for (const UniquePtr<LexerStatement>& statement : statements)
829 {
830 statement->Process(lexerContext);
831 }
832 }
833 private Uuid moduldeId;
834 private ustring api;
835 private List<UniquePtr<LexerStatement>> statements;
836 private List<UniquePtr<Variable>> variables;
837 private Actions actions;
838 private Nfa masterNfa;
839 private Dfa dfa;
840 }
841 public class LexerFile
842 {
843 public void Add(Declaration* declaration)
844 {
845 declarations.Add(UniquePtr<Declaration>(declaration));
846 declarationMap[declaration->Name()] = declaration;
847 }
848 public void Process(const string& root, bool verbose, bool debug, bool noClassMapCompression, LexerContext& lexerContext)
849 {
850 for (UniquePtr<Declaration>& d : declarations)
851 {
852 d->FillContext(lexerContext);
853 }
854 if (!(lexerContext.GetTokens() != null))
855 {
856 throw Exception("error: no tokens defined");
857 }
858 if (!(lexerContext.GetLexer() != null))
859 {
860 throw Exception("error: no lexer defined");
861 }
862 for (UniquePtr<Declaration>& d : declarations)
863 {
864 d->Process(root, verbose, lexerContext);
865 }
866 lexerContext.MakeCanonicalClasses();
867 lexerContext.MakeClassPartition(debug);
868 lexerContext.MakeClassMap(root, verbose, noClassMapCompression);
869 lexerContext.GetLexer()->MakeMasterNfa(lexerContext);
870 lexerContext.GetLexer()->MakeDfa(lexerContext);
871 lexerContext.GetLexer()->WriteAutomaton(root, verbose, lexerContext);
872 }
873 private List<UniquePtr<Declaration>> declarations;
874 private Map<ustring, Declaration*> declarationMap;
875 }
876 public const char* LexerGeneratorVersionStr()
877 {
878 return "4.0.0";
879 }
880 }