1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 [hpp]#include <sngcpp/parser/ParserApi.hpp>
  7 [hpp]#include <sngcpp/parser/ParsingContext.hpp>
  8 [hpp]#include <sngcpp/ast/Declaration.hpp>
  9 [cpp]#include <sngcpp/parser/SourceFile.hpp>
 10 [cpp]#include <sngcpp/parser/Declarator.hpp>
 11 [cpp]#include <sngcpp/parser/Identifier.hpp>
 12 [cpp]#include <sngcpp/parser/TypeExpr.hpp>
 13 [cpp]#include <sngcpp/parser/Function.hpp>
 14 [cpp]#include <sngcpp/parser/Class.hpp>
 15 [cpp]#include <sngcpp/parser/Enumeration.hpp>
 16 [cpp]#include <sngcpp/parser/Literal.hpp>
 17 [cpp]#include <sngcpp/parser/Template.hpp>
 18 [cpp]#include <sngcpp/lexer/CppLexer.hpp>
 19 [cpp]#include <sngcpp/lexer/CppTokens.hpp>
 20 
 21 using namespace CppTokens;
 22 using namespace soulng::lexer;
 23 
 24 parser api(SNGCPP_PARSER_API) DeclarationParser
 25 {
 26     uselexer CppLexer;
 27 
 28     using SourceFileParser.Declarations;
 29     using DeclaratorParser.InitDeclarator;
 30     using DeclaratorParser.Declarator;
 31     using IdentifierParser.Identifier;
 32     using IdentifierParser.QualifiedIdNode;
 33     using TypeExprParser.TypeExpr;
 34     using FunctionParser.FunctionDefinition;
 35     using ClassParser.SpecialMemberFunctionDefinition;
 36     using TemplateParser.TemplateDeclaration;
 37     using TemplateParser.ExplicitInstantiation;
 38     using TemplateParser.ExplicitSpecialization;
 39     using ClassParser.ClassDeclaration;
 40     using ClassParser.ForwardClassDeclaration;
 41     using EnumerationParser.EnumDeclaration;
 42     using EnumerationParser.OpaqueEnumDeclaration;
 43     using LiteralParser.StringLiteral;
 44 
 45     Declaration(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
 46         ::= NamespaceDefinition(ctx):namespaceDefinition{ return namespaceDefinition; }
 47         |   FunctionDefinition(ctx):functionDefinition{ return functionDefinition; }
 48         |   SpecialMemberFunctionDefinition(ctx):specialMemberFunctionDefinition{ return specialMemberFunctionDefinition; }
 49         |   TemplateDeclaration(ctx):templateDeclaration{ return templateDeclaration; }
 50         |   ExplicitInstantiation(ctx):explicitInstantiation{ return explicitInstantiation; }
 51         |   ExplicitSpecialization(ctx):explicitSpecialization{ return explicitSpecialization; }
 52         |   ClassDeclaration(ctx):classDeclaration{ return classDeclaration; }
 53         |   EnumDeclaration(ctx):enumDeclaration{ return enumDeclaration; }
 54         |   LinkageSpecification(ctx):linkageSpecification{ return linkageSpecification; }
 55         |   BlockDeclaration(ctx):blockDeclaration{ return blockDeclaration; }
 56         ;
 57 
 58     NamespaceDefinition(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
 59         ::= NamedNamespaceDefinition(ctx):namedNamespaceDefinition{ return namedNamespaceDefinition; }
 60         |   UnnamedNamespaceDefinition(ctx):unnamedNamespaceDefinition{ return unnamedNamespaceDefinition; }
 61         ;
 62 
 63     NamedNamespaceDefinition(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr ns, var Span s) : sngcpp::ast::Node*
 64         ::= NAMESPACE{ s = span; } Identifier:id LBRACE{ s.end = span.end; ns.reset(new sngcpp::ast::NamespaceNode(s, id)); } Declarations(ctx, ns.get()):declarations RBRACE!
 65         {
 66             return ns.release();
 67         }
 68         ;
 69 
 70     UnnamedNamespaceDefinition(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr ns, var Span s) : sngcpp::ast::Node*
 71         ::= NAMESPACE{ s = span; } LBRACE{ s.end = span.end; ns.reset(new sngcpp::ast::NamespaceNode(s)); } Declarations(ctx, ns.get()):declarations RBRACE!
 72         {
 73             return ns.release();
 74         }
 75         ;
 76 
 77     BlockDeclaration(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
 78         ::= SimpleDeclaration(ctx):simpleDeclaration{ return simpleDeclaration; }
 79         |   AliasDeclaration(ctx):aliasDeclaration{ return aliasDeclaration; }
 80         |   UsingDirective(ctx):usingDirective{ return usingDirective; }
 81         |   UsingDeclaration(ctx):usingDeclaration{ return usingDeclaration; }
 82         |   OpaqueEnumDeclaration(ctx):opaqueEnumDeclaration{ return opaqueEnumDeclaration; }
 83         |   TypedefDeclaration(ctx):typedefDeclaration{ return typedefDeclaration; }
 84         |   ForwardClassDeclaration(ctx):forwardClassDeclaration{ return forwardClassDeclaration; }
 85         ;
 86 
 87     SimpleDeclaration(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
 88         ::= DeclSpecifiers:declSpecifiers{ s = span; } TypeExpr(ctx):typeExpr InitDeclarator(ctx):initDeclarator SEMICOLON
 89         {
 90             s.end = span.end;
 91             return new sngcpp::ast::SimpleDeclarationNode(s, declSpecifiers, typeExpr, initDeclarator);
 92         }
 93         ;
 94 
 95     DeclSpecifiers(var sngcpp::ast::Specifier specifiers) : sngcpp::ast::Specifier
 96         ::= ((DeclSpecifier:declSpecifier{ specifiers = specifiers | declSpecifier; })*)
 97         {
 98             return specifiers;
 99         }
100         ;
101 
102     DeclSpecifier : sngcpp::ast::Specifier
103         ::= StorageClassSpecifier:storageClassSpecifier{ return storageClassSpecifier; }
104         |   FunctionSpecifier:functionSpecifier{ return functionSpecifier; }
105         |   FRIEND{ return sngcpp::ast::Specifier::friend_; }
106         |   CONSTEXPR{ return sngcpp::ast::Specifier::constExpr; }
107         |   __DECLSPEC LPAREN ID RPAREN{ return sngcpp::ast::Specifier::extension; }
108         |   __THREAD{ return sngcpp::ast::Specifier::extension; }
109         ;
110 
111     StorageClassSpecifier : sngcpp::ast::Specifier
112         ::= REGISTER{ return sngcpp::ast::Specifier::register_; }
113         |   STATIC{ return sngcpp::ast::Specifier::static_; }
114         |   EXTERN{ return sngcpp::ast::Specifier::extern_; }
115         |   MUTABLE{ return sngcpp::ast::Specifier::mutable_; }
116         ;
117 
118     FunctionSpecifier : sngcpp::ast::Specifier
119         ::= INLINE{ return sngcpp::ast::Specifier::inline_; }
120         |   VIRTUAL{ return sngcpp::ast::Specifier::virtual_; }
121         |   EXPLICIT{ return sngcpp::ast::Specifier::explicit_; }
122         ;
123 
124     AliasDeclaration(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
125         ::= USING{ s = span; } Identifier:id ASSIGN TypeExpr(ctx):typeExpr! SEMICOLON!{ s.end = span.end; return new sngcpp::ast::AliasDeclarationNode(s, id, typeExpr); }
126         ;
127 
128     UsingDirective(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
129         ::= USING{ s = span; } NAMESPACE QualifiedIdNode(ctx):qid! SEMICOLON!
130         {
131             s.end = span.end;
132             sngcpp::ast::Node* value = new sngcpp::ast::UsingDirectiveNode(s, qid);
133             ctx->GetSourceFileNode()->AddUsingDirectiveOrDeclaration(value);
134             return value;
135         }
136         ;
137 
138     UsingDeclaration(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
139         ::= USING{ s = span; } QualifiedIdNode(ctx):qid SEMICOLON
140         {
141             s.end = span.end;
142             sngcpp::ast::Node* value = new sngcpp::ast::UsingDeclarationNode(s, qid);
143             ctx->GetSourceFileNode()->AddUsingDirectiveOrDeclaration(value);
144             return value;
145         }
146         ;
147 
148     TypedefDeclaration(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
149         ::= TYPEDEF{ s = span; } TypeExpr(ctx):typeExpr! Declarator(ctx):declarator! SEMICOLON!
150         {
151             s.end = span.end;
152             return new sngcpp::ast::TypedefNode(s, typeExpr, declarator);
153         }
154         ;
155 
156     LinkageSpecification(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr ls, var Span s) : sngcpp::ast::Node*
157         ::= EXTERN{ s = span; } StringLiteral:language{ s.end = span.end; ls.reset(new sngcpp::ast::LinkageSpecificationNode(s, language)); }
158             (LBRACE (Declaration(ctx):d1{ ls->AddDeclaration(span, d1); })* RBRACE! | Declaration(ctx):d2{ ls->AddDeclaration(span, d2); })
159         {
160             return ls.release();
161         }
162         ;
163 }