1
2
3
4
5
6 [hpp]#include <sngcpp/parser/ParserApi.hpp>
7 [hpp]#include <sngcpp/parser/ParsingContext.hpp>
8 [hpp]#include <sngcpp/ast/Template.hpp>
9 [cpp]#include <sngcpp/parser/Declaration.hpp>
10 [cpp]#include <sngcpp/parser/Expression.hpp>
11 [cpp]#include <sngcpp/parser/Function.hpp>
12 [cpp]#include <sngcpp/parser/Identifier.hpp>
13 [cpp]#include <sngcpp/parser/TypeExpr.hpp>
14 [cpp]#include <sngcpp/lexer/CppLexer.hpp>
15 [cpp]#include <sngcpp/lexer/CppTokens.hpp>
16
17 using namespace CppTokens;
18 using namespace soulng::lexer;
19
20 parser api(SNGCPP_PARSER_API) TemplateParser
21 {
22 uselexer CppLexer;
23
24 using IdentifierParser.Identifier;
25 using DeclarationParser.Declaration;
26 using ExpressionParser.ConstantExpression;
27 using ExpressionParser.ConditionalExpression;
28 using FunctionParser.ParameterDeclaration;
29 using TypeExprParser.TypeExpr;
30
31 TemplateDeclaration(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
32 ::= TEMPLATE{ s = span; } LANGLE TemplateParameterList(ctx):templateParameterList RANGLE! Declaration(ctx):declaration!
33 {
34 s.end = span.end;
35 return new sngcpp::ast::TemplateDeclarationNode(s, templateParameterList, declaration);
36 }
37 ;
38
39 TemplateParameterList(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr node, var Span s) : sngcpp::ast::Node*
40 ::=
41 ( TemplateParameter(ctx):left{ s = span; node.reset(left); }
42 (COMMA TemplateParameter(ctx):right{ s.end = span.end; node.reset(new sngcpp::ast::TemplateParameterSequenceNode(s, node.release(), right)); })*
43 )
44 {
45 return node.release();
46 }
47 ;
48
49 TemplateParameter(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
50 ::= TypeParameter(ctx):typeParam{ return typeParam; }
51 | ParameterDeclaration(ctx):paramDeclaration{ return paramDeclaration; }
52 ;
53
54 TypeParameter(sngcpp::cppparser::ParsingContext* ctx, var bool typenameUsed, var Span s) : sngcpp::ast::Node*
55 ::= ((CLASS{ s = span; typenameUsed = false; } | TYPENAME{ s = span; typenameUsed = true; }) Identifier:id{ s.end = span.end; } (ASSIGN TypeExpr(ctx):typeExpr{ s.end = span.end; })?)
56 {
57 return new sngcpp::ast::TypeParameterNode(s, id, typeExpr, typenameUsed);
58 }
59 ;
60
61 SimpleTemplateId(sngcpp::cppparser::ParsingContext* ctx, var int arity, var Span s) : sngcpp::ast::Node*
62 ::=
63 ( TemplateName:templateName{ s = span; }
64 LANGLE{ ++lexer.langleCount; ctx->BeginParsingTemplateId(); }
65 TemplateArgumentList(ctx, &arity):args?
66 RANGLE{ --lexer.langleCount; ctx->EndParsingTemplateId(); } / { --lexer.langleCount; ctx->EndParsingTemplateId(); }
67 )
68 {
69 s.end = span.end;
70 return new sngcpp::ast::TemplateIdNode(s, templateName, args, arity);
71 }
72 ;
73
74 TemplateId(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
75 ::= SimpleTemplateId(ctx):simpleTemplateId{ return simpleTemplateId; }
76 ;
77
78 TemplateName : sngcpp::ast::IdentifierNode*
79 ::= Identifier:id{ return new sngcpp::ast::IdentifierNode(span, id); }
80 ;
81
82 TemplateArgumentList(sngcpp::cppparser::ParsingContext* ctx, int* arity, var std::unique_ptr arg) : sngcpp::ast::Node*
83 ::=
84 ( TemplateArgument(ctx):left{ arg.reset(new sngcpp::ast::TemplateArgumentNode(span, left)); ++*arity; }
85 (COMMA TemplateArgument(ctx):right{ arg.reset(new sngcpp::ast::TemplateArgumentSequenceNode(span, arg.release(), new sngcpp::ast::TemplateArgumentNode(span, right))); ++*arity; })*
86 )
87 {
88 return arg.release();
89 }
90 ;
91
92 TemplateArgument(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
93 ::= TypeExpr(ctx):typeExpr{ return typeExpr; }
94 | ConditionalExpression(ctx):condExpr{ return condExpr; }
95 ;
96
97 ExplicitInstantiation(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
98 ::= TEMPLATE{ s = span; } Declaration(ctx):declaration{ s.end = span.end; return new sngcpp::ast::ExplicitInstantiationNode(s, declaration); }
99 ;
100
101 ExplicitSpecialization(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
102 ::= TEMPLATE{ s = span; } LANGLE RANGLE Declaration(ctx):declaration{ s.end = span.end; return new sngcpp::ast::ExplicitSpecializationNode(s, declaration); }
103 ;
104 }