1 // =================================
 2 // Copyright (c) 2021 Seppo Laakko
 3 // Distributed under the MIT license
 4 // =================================
 5 
 6 [hpp]#include <sngcm/cmparser/ParserApi.hpp>
 7 [hpp]#include <sngcm/ast/Template.hpp>
 8 [hpp]#include <sngcm/cmparser/Identifier.hpp>
 9 [hpp]#include <sngcm/cmparser/TypeExpr.hpp>
10 [hpp]#include <sngcm/cmparser/ParsingContext.hpp>
11 [cpp]#include <sngcm/cmlexer/CmajorLexer.hpp>
12 [cpp]#include <sngcm/cmlexer/CmajorTokens.hpp>
13 
14 using namespace sngcm::ast;
15 using namespace CmajorTokens;
16 
17 parser api(SNGCM_PARSER_API) TemplateParser
18 {
19     uselexer CmajorLexer;
20 
21     using IdentifierParser.Identifier;
22     using IdentifierParser.QualifiedId;
23     using TypeExprParser.TypeExpr;
24 
25     TemplateId(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr templateId, var Span e) : TemplateIdNode*
26         ::= empty{ ctx->BeginParsingTemplateId(); }
27             (QualifiedId(moduleId):primary{ templateId.reset(new TemplateIdNode(span, *moduleId, primary)); }
28             LANGLE{ ++lexer.leftAngleCount; }
29             ((TypeExpr(moduleId, ctx):templateArg{ templateId->AddTemplateArgument(templateArg); } % COMMA) RANGLE{ e = span; }){ --lexer.leftAngleCount; } / { --lexer.leftAngleCount; })
30         {
31             templateId->SetSpanEnd(e.end);
32             ctx->EndParsingTemplateId();
33             return templateId.release();
34         }
35         /
36         {
37             ctx->EndParsingTemplateId();
38         }
39         ;
40 
41     TemplateParameter(boost::uuids::uuid* moduleId, ParsingContext* ctx) : TemplateParameterNode*
42         ::= (Identifier(moduleId):id (ASSIGN TypeExpr(moduleId, ctx):type)?){ return new TemplateParameterNode(span, *moduleId, id, type); }
43         ;
44 
45     TemplateParameterList(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::Node* owner)
46         ::= LANGLE (TemplateParameter(moduleId, ctx):tp{ owner->AddTemplateParameter(tp); } % COMMA) RANGLE!
47         ;
48 
49     InstantiationRequest(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s, var std::unique_ptr fullInstantiationRequestNode) : FullInstantiationRequestNode*
50         ::= (NEW{ s = span; } CLASS TemplateId(moduleId, ctx):templateId{ s.end = span.end; fullInstantiationRequestNode.reset(new FullInstantiationRequestNode(s, *moduleId, templateId)); } SEMICOLON)
51         {
52             return fullInstantiationRequestNode.release();
53         }
54         ;
55 
56     ruleinfo
57     {
58         (TemplateId, "template identifier"), 
59         (TemplateParameter, "template parameter"), 
60         (TemplateParameterList, "template parameter list"),
61         (InstantiationRequest, "instantiation request")
62     }
63 }