1 // =================================
 2 // Copyright (c) 2021 Seppo Laakko
 3 // Distributed under the MIT license
 4 // =================================
 5 
 6 using Cm.Ast;
 7 using ParserFileTokens;
 8 
 9 parser TemplateParser
10 {
11     uselexer ParserFileLexer;
12 
13     using IdentifierParser.Identifier;
14     using IdentifierParser.QualifiedId;
15     using TypeExprParser.TypeExpr;
16 
17     TemplateId(ParsingContext* ctx, var UniquePtr<TemplateIdNode> templateId, var Span e) : Node*
18         ::= empty{ ctx->BeginParsingTemplateId(); }
19             (QualifiedId(ctx):primary{ templateId.Reset(new TemplateIdNode(span, ctx->ModuleId(), primary)); }
20             LANGLE{ ++lexer.leftAngleCount; }
21             ((TypeExpr(ctx):templateArg{ templateId->AddTemplateArgument(templateArg); } % COMMA) RANGLE{ e = span; }){ --lexer.leftAngleCount; } / { --lexer.leftAngleCount; })
22         {
23             templateId->SetSpanEnd(e.end);
24             ctx->EndParsingTemplateId();
25             return templateId.Release();
26         }
27         /
28         {
29             ctx->EndParsingTemplateId();
30         }
31         ;
32 
33     TemplateParameter(ParsingContext* ctx) : TemplateParameterNode*
34         ::= (Identifier(ctx):id (ASSIGN TypeExpr(ctx):type)?){ return new TemplateParameterNode(span, ctx->ModuleId(), id, type); }
35         ;
36 
37     TemplateParameterList(ParsingContext* ctx, Node* owner)
38         ::= LANGLE (TemplateParameter(ctx):tp{ owner->AddTemplateParameter(tp); } % COMMA) RANGLE!
39         ;
40 
41     ruleinfo
42     {
43         (TemplateId, "template identifier"), (TemplateParameter, "template parameter"), (TemplateParameterList, "template parameter list")
44     }
45 }