1
2
3
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 }