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 }