1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <sng2html/sng2html/Parser.hpp>
  7 #include <sng2html/sng2html/Visitor.hpp>
  8 #include <soulng/util/Unicode.hpp>
  9 
 10 namespace sng2html { namespace sng2html {
 11 
 12 using namespace soulng::unicode;
 13 
 14 Parser::Parser(const std::u32string& name_) : name(name_)parent(nullptr)parentIsList(false)
 15 {
 16 }
 17 
 18 Parser::~Parser()
 19 {
 20 }
 21 
 22 Parser* Parser::Clone() const
 23 {
 24     throw std::runtime_error("this class does not support clone operation");
 25 }
 26 
 27 UnaryParser::UnaryParser(const std::u32string& name_Parser* child_) : Parser(name_)child(child_)
 28 {
 29     child->SetParent(this);
 30 }
 31 
 32 BinaryParser::BinaryParser(const std::u32string& name_Parser* left_Parser* right_) : Parser(name_)left(left_)right(right_)
 33 {
 34     left->SetParent(this);
 35     right->SetParent(this);
 36 }
 37 
 38 EmptyParser::EmptyParser() : Parser(U"empty")
 39 {
 40 }
 41 
 42 Parser* EmptyParser::Clone() const
 43 {
 44     return new EmptyParser();
 45 }
 46 
 47 void EmptyParser::Accept(Visitor& visitor)
 48 {
 49     visitor.Visit(*this);
 50 }
 51 
 52 TokenParser::TokenParser(const std::u32string& tokenName_) : Parser(tokenName_)tokenName(tokenName_)
 53 {
 54 }
 55 
 56 Parser* TokenParser::Clone() const
 57 {
 58     return new TokenParser(tokenName);
 59 }
 60 
 61 void TokenParser::Accept(Visitor& visitor)
 62 {
 63     visitor.Visit(*this);
 64 }
 65 
 66 CharParser::CharParser(char32_t chr_) : Parser(std::u32string(1chr_))chr(chr_)
 67 {
 68 }
 69 
 70 Parser* CharParser::Clone() const
 71 {
 72     return new CharParser(chr);
 73 }
 74 
 75 void CharParser::Accept(Visitor& visitor)
 76 {
 77     visitor.Visit(*this);
 78 }
 79 
 80 StringParser::StringParser(const std::u32string& str_) : Parser(str_)str(str_)
 81 {
 82 }
 83 
 84 Parser* StringParser::Clone() const
 85 {
 86     return new StringParser(str);
 87 }
 88 
 89 void StringParser::Accept(Visitor& visitor)
 90 {
 91     visitor.Visit(*this);
 92 }
 93 
 94 void StringParser::SetArrayName(const std::string& arrayName_)
 95 {
 96     arrayName = arrayName_;
 97 }
 98 
 99 CharSetParser::CharSetParser(const CharSet& set_) : Parser(U"charset")set(set_)
100 {
101 }
102 
103 Parser* CharSetParser::Clone() const
104 {
105     return new CharSetParser(set);
106 }
107 
108 void CharSetParser::Accept(Visitor& visitor)
109 {
110     visitor.Visit(*this);
111 }
112 
113 void CharSetParser::SetArrayName(const std::string& arrayName_)
114 {
115     arrayName = arrayName_;
116 }
117 
118 OptionalParser::OptionalParser(Parser* child_) : UnaryParser(U"optional"child_)
119 {
120 }
121 
122 Parser* OptionalParser::Clone() const
123 {
124     return new OptionalParser(Child()->Clone());
125 }
126 
127 void OptionalParser::Accept(Visitor& visitor)
128 {
129     visitor.Visit(*this);
130 }
131 
132 KleeneParser::KleeneParser(Parser* child_) : UnaryParser(U"kleene"child_)
133 {
134 }
135 
136 Parser* KleeneParser::Clone() const
137 {
138     return new KleeneParser(Child()->Clone());
139 }
140 
141 void KleeneParser::Accept(Visitor& visitor)
142 {
143     visitor.Visit(*this);
144 }
145 
146 PositiveParser::PositiveParser(Parser* child_) : UnaryParser(U"positive"child_)
147 {
148 }
149 
150 Parser* PositiveParser::Clone() const
151 {
152     return new PositiveParser(Child()->Clone());
153 }
154 
155 void PositiveParser::Accept(Visitor& visitor)
156 {
157     visitor.Visit(*this);
158 }
159 
160 ExpectationParser::ExpectationParser(Parser* child_) : UnaryParser(U"expectation"child_)
161 {
162 }
163 
164 Parser* ExpectationParser::Clone() const
165 {
166     return new ExpectationParser(Child()->Clone());
167 }
168 
169 void ExpectationParser::Accept(Visitor& visitor)
170 {
171     visitor.Visit(*this);
172 }
173 
174 GroupingParser::GroupingParser(Parser* child_) : UnaryParser(U"grouping"child_)
175 {
176 }
177 
178 Parser* GroupingParser::Clone() const
179 {
180     return new GroupingParser(Child()->Clone());
181 }
182 
183 void GroupingParser::Accept(Visitor& visitor)
184 {
185     visitor.Visit(*this);
186 }
187 
188 SequenceParser::SequenceParser(Parser* left_Parser* right_) : BinaryParser(U"sequence"left_right_)
189 {
190 }
191 
192 Parser* SequenceParser::Clone() const
193 {
194     return new SequenceParser(Left()->Clone()Right()->Clone());
195 }
196 
197 void SequenceParser::Accept(Visitor& visitor)
198 {
199     visitor.Visit(*this);
200 }
201 
202 bool SequenceParser::IsAction() const
203 {
204     if (Left()->IsEmptyOrEmptyActionParser())
205     {
206         return Right()->IsAction();
207     }
208     else if (Right()->IsEmptyOrEmptyActionParser())
209     {
210         return Left()->IsAction();
211     }
212     else
213     {
214         return false;
215     }
216 }
217 
218 AlternativeParser::AlternativeParser(Parser* left_Parser* right_) : BinaryParser(U"alternative"left_right_)
219 {
220 }
221 
222 Parser* AlternativeParser::Clone() const
223 {
224     return new AlternativeParser(Left()->Clone()Right()->Clone());
225 }
226 
227 void AlternativeParser::Accept(Visitor& visitor)
228 {
229     visitor.Visit(*this);
230 }
231 
232 DifferenceParser::DifferenceParser(Parser* left_Parser* right_) : BinaryParser(U"difference"left_right_)
233 {
234 }
235 
236 Parser* DifferenceParser::Clone() const
237 {
238     return new DifferenceParser(Left()->Clone()Right()->Clone());
239 }
240 
241 void DifferenceParser::Accept(Visitor& visitor)
242 {
243     visitor.Visit(*this);
244 }
245 
246 ListParser::ListParser(Parser* left_Parser* right_) :
247     UnaryParser(U"list"new SequenceParser(left_new KleeneParser(new SequenceParser(right_left_->Clone()))))left(left_)right(right_)
248 {
249     left->SetParentIsList();
250     right->SetParentIsList();
251 }
252 
253 Parser* ListParser::Clone() const
254 {
255     return new ListParser(left->Clone()right->Clone());
256 }
257 
258 void ListParser::Accept(Visitor& visitor)
259 {
260     visitor.Visit(*this);
261 }
262 
263 ActionParser::ActionParser(soulng::cppcode::CompoundStatement* successCode_soulng::cppcode::CompoundStatement* failCode_Parser* child_) :
264     UnaryParser(U"action"child_)successCode(successCode_)failCode(failCode_)
265 {
266     if (successCode && !successCode->IsOwned())
267     {
268         successCode->SetOwned();
269         ownedSuccessCode.reset(successCode);
270     }
271     if (failCode && !failCode->IsOwned())
272     {
273         failCode->SetOwned();
274         ownedFailCode.reset(failCode);
275     }
276 }
277 
278 ActionParser::~ActionParser()
279 {
280 
281 }
282 
283 Parser* ActionParser::Clone() const
284 {
285     return new ActionParser(successCodefailCodeChild()->Clone());
286 }
287 
288 void ActionParser::Accept(Visitor& visitor)
289 {
290     visitor.Visit(*this);
291 }
292 
293 bool ActionParser::IsActionToken() const
294 {
295     return Child()->IsToken();
296 }
297 
298 Parameter::Parameter(soulng::cppcode::TypeId* type_const std::u32string& name_) : type(type_)name(name_)variable(false)
299 {
300 }
301 
302 Parameter::Parameter(soulng::cppcode::TypeId* type_const std::u32string& name_bool variable_) : type(type_)name(name_)variable(variable_)
303 {
304 }
305 
306 Parameter::~Parameter()
307 {
308 }
309 
310 Variable::Variable(soulng::cppcode::TypeId* type_const std::u32string& name_) : Parameter(type_name_true)
311 {
312 }
313 
314 NonterminalParser::NonterminalParser(const std::u32string& name_const std::u32string& ruleName_) : Parser(name_)ruleName(ruleName_)rule(nullptr)
315 {
316 }
317 
318 Parser* NonterminalParser::Clone() const
319 {
320     NonterminalParser* clone = new NonterminalParser(Name()ruleName);
321     clone->args = args;
322     return clone;
323 }
324 
325 void NonterminalParser::Accept(Visitor& visitor)
326 {
327     visitor.Visit(*this);
328 }
329 
330 void NonterminalParser::SetArguments(soulng::cppcode::ExpressionList* args_)
331 {
332     if (args_)
333     {
334         for (const auto& arg : args_->Args())
335         {
336             args.push_back(arg);
337             if (!arg->IsOwned())
338             {
339                 arg->SetOwned();
340                 ownedArgs.push_back(std::unique_ptr<soulng::cppcode::CppObject>(arg));
341             }
342         }
343     }
344 }
345 
346 RuleParser::RuleParser(const std::u32string& name_) : Parser(name_)hasReturn(false)
347 {
348 }
349 
350 GrammarParser* RuleParser::GetGrammar() const
351 {
352     if (Parent())
353     {
354         if (Parent()->IsGrammar())
355         {
356             return static_cast<GrammarParser*>(Parent());
357         }
358         else
359         {
360             throw std::runtime_error("error: parent of rule not grammar");
361         }
362     }
363     else
364     {
365         throw std::runtime_error("error: rule has no parent");
366     }
367 }
368 
369 void RuleParser::SetDefinition(Parser* definition_)
370 {
371     definition.reset(definition_);
372 }
373 
374 void RuleParser::AddParamOrVariable(Parameter* paramOrVariable)
375 {
376     if (paramOrVariable->variable)
377     {
378         variables.push_back(std::unique_ptr<Variable>(static_cast<Variable*>(paramOrVariable)));
379     }
380     else
381     {
382         parameters.push_back(std::unique_ptr<Parameter>(paramOrVariable));
383     }
384 }
385 
386 void RuleParser::SetReturnType(soulng::cppcode::TypeId* returnType_)
387 {
388     returnType.reset(returnType_);
389 }
390 
391 void RuleParser::Accept(Visitor& visitor)
392 {
393     visitor.Visit(*this);
394 }
395 
396 void RuleParser::AddNonterminal(NonterminalParser* nonterminal)
397 {
398     nonterminals.push_back(nonterminal);
399 }
400 
401 void RuleParser::SetInfo(const std::u32string& info_)
402 {
403     info = info_;
404 }
405 
406 GrammarParser::GrammarParser(const std::u32string& name_const std::u32string& api_) : Parser(name_)api(api_)main(false)
407 {
408 }
409 
410 void GrammarParser::Accept(Visitor& visitor)
411 {
412     visitor.Visit(*this);
413 }
414 
415 void GrammarParser::AddUsing(const std::u32string& using_)
416 {
417     usings.push_back(using_);
418 }
419 
420 void GrammarParser::AddRule(RuleParser* rule)
421 {
422     rule->SetParent(this);
423     rules.push_back(std::unique_ptr<RuleParser>(rule));
424     ruleMap[rule->Name()] = rule;
425 }
426 
427 void GrammarParser::MapRule(RuleParser* rule)
428 {
429     ruleMap[rule->Name()] = rule;
430 }
431 
432 RuleParser* GrammarParser::GetRule(const std::u32string& ruleName) const
433 {
434     auto it = ruleMap.find(ruleName);
435     if (it != ruleMap.cend())
436     {
437         return it->second;
438     }
439     else
440     {
441         throw std::runtime_error("rule '" + ToUtf8(ruleName) + "' not found from parser '" + ToUtf8(Name()) + "'");
442     }
443 }
444 
445 void GrammarParser::AddRuleInfo(const std::u32string& ruleNameconst std::u32string& ruleInfo)
446 {
447     ruleInfos.push_back(std::make_pair(ruleNameruleInfo));
448 }
449 
450 } } // namespace sng2html::sng2html