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/Class.hpp>
  9 [cpp]#include <sngcpp/parser/Declaration.hpp>
 10 [cpp]#include <sngcpp/parser/Declarator.hpp>
 11 [cpp]#include <sngcpp/parser/Enumeration.hpp>
 12 [cpp]#include <sngcpp/parser/Expression.hpp>
 13 [cpp]#include <sngcpp/parser/Function.hpp>
 14 [cpp]#include <sngcpp/parser/Identifier.hpp>
 15 [cpp]#include <sngcpp/parser/Literal.hpp>
 16 [cpp]#include <sngcpp/parser/Template.hpp>
 17 [cpp]#include <sngcpp/parser/TypeExpr.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) ClassParser
 25 {
 26     uselexer CppLexer;
 27 
 28     using DeclaratorParser.Declarator;
 29     using DeclaratorParser.BracedInitializerList;
 30     using DeclaratorParser.BraceOrEqualInitializer;
 31     using DeclarationParser.AliasDeclaration;
 32     using DeclarationParser.DeclSpecifiers;
 33     using DeclarationParser.UsingDeclaration;
 34     using DeclarationParser.TypedefDeclaration;
 35     using IdentifierParser.QualifiedIdNode;
 36     using EnumerationParser.EnumDeclaration;
 37     using ExpressionParser.ArgumentList;
 38     using FunctionParser.FunctionBody;
 39     using FunctionParser.FunctionDefinition;
 40     using LiteralParser.IntegerLiteral;
 41     using TemplateParser.TemplateDeclaration;
 42     using TypeExprParser.TypeExpr;
 43 
 44     ClassDeclaration(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
 45         ::= ClassSpecifier(ctx):classSpecifier SEMICOLON{ return classSpecifier; }
 46         ;
 47 
 48     ClassSpecifier(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr classNode) : sngcpp::ast::Node*
 49         ::=
 50         (   ClassHead(ctx):classHead{ classNode.reset(classHead); }
 51             LBRACE{ classNode->SetOpenBraceSpan(span); }
 52             MemberSpecifications(ctx, classNode.get()):memberSpecifications
 53             RBRACE{ classNode->SetCloseBraceSpan(span); }
 54         )
 55         {
 56             return classNode.release();
 57         }
 58         ;
 59 
 60     MemberSpecifications(sngcpp::cppparser::ParsingContext* ctx, sngcpp::ast::ClassNode* classNode)
 61         ::= MemberSpecification(ctx, classNode):memberSpecification*
 62         ;
 63 
 64     MemberSpecification(sngcpp::cppparser::ParsingContext* ctx, sngcpp::ast::ClassNode* classNode, var Span s)
 65         ::=
 66         (   AccessSpecifier:accessSpecifier{ s = span; } COLON
 67             (MemberDeclaration(ctx):m1{ s.end = span.end; classNode->AddDeclaration(s, new sngcpp::ast::MemberAccessDeclarationNode(s, accessSpecifier, m1, true)); })*
 68         |   (MemberDeclaration(ctx):m2{ s = span; classNode->AddDeclaration(s, new sngcpp::ast::MemberAccessDeclarationNode(s, classNode->DefaultAccess(), m2, false)); })+
 69         )
 70         ;
 71 
 72     MemberDeclaration(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr declarator, var Span s) : sngcpp::ast::Node*
 73         ::= DeclSpecifiers:declSpecifiers{ s = span; }
 74             TypeExpr(ctx):typeExpr
 75             Declarator(ctx):d{ declarator.reset(d); }
 76             VirtPureSpecifiers(sngcpp::ast::IsFunctionDeclarator(declarator.get())):virtPureSpecifiers
 77             BraceOrEqualInitializer(ctx):initializer? SEMICOLON{ s.end = span.end; return new sngcpp::ast::MemberDeclarationNode(s, declSpecifiers | virtPureSpecifiers, typeExpr, declarator.release(), initializer); }
 78         |   SpecialMemberFunctionDeclaration(ctx):specialMemberFunctionDeclaration{ return specialMemberFunctionDeclaration; }
 79         |   (FunctionDefinition(ctx):functionDefinition SEMICOLON?){ return functionDefinition; }
 80         |   (SpecialMemberFunctionDefinition(ctx):specialMemberFunctionDefition SEMICOLON?){ return specialMemberFunctionDefition; }
 81         |   UsingDeclaration(ctx):usingDeclaration{ return usingDeclaration; }
 82         |   TypedefDeclaration(ctx):typedefDeclaration{ return typedefDeclaration; }
 83         |   TemplateDeclaration(ctx):templateDeclaration{ return templateDeclaration; }
 84         |   ClassDeclaration(ctx):classDeclaration{ return classDeclaration; }
 85         |   EnumDeclaration(ctx):enumDeclaration{ return enumDeclaration; }
 86         |   AliasDeclaration(ctx):aliasDeclaration{ return aliasDeclaration; }
 87         |   ForwardClassDeclaration(ctx):forwardClassDeclaration{ return forwardClassDeclaration; }
 88         ;
 89 
 90     SpecialMemberFunctionDeclaration(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr declarator, var Span s) : sngcpp::ast::Node*
 91         ::= DeclSpecifiers:declSpecifiers{ s = span; }
 92             Declarator(ctx):d{ declarator.reset(d); pass = sngcpp::ast::IsFunctionDeclarator(declarator.get()); }
 93             VirtPureSpecifiers(true):virtPureSpecifiers
 94             SEMICOLON
 95         {
 96             s.end = span.end;
 97             return new sngcpp::ast::MemberDeclarationNode(s, declSpecifiers | virtPureSpecifiers, nullptr, declarator.release(), nullptr);
 98         }
 99         ;
100 
101     ClassHead(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::ClassNode*
102         ::= (ClassKey:classKey{ s = span; } ClassName(ctx):className ClassVirtSpecifiers:classVirtSpecifiers{ s.end = span.end; } (BaseClause(ctx):baseClause{ s.end = span.end; })?)
103         {
104             return new sngcpp::ast::ClassNode(s, classKey, className, classVirtSpecifiers, baseClause);
105         }
106         ;
107 
108     ForwardClassDeclaration(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
109         ::= ClassKey:classKey{ s = span; } ClassName(ctx):className SEMICOLON{ s.end = span.end; return new sngcpp::ast::ForwardClassDeclarationNode(s, classKey, className); }
110         ;
111 
112     ClassKey : sngcpp::ast::ClassKey
113         ::= CLASS{ return sngcpp::ast::ClassKey::class_; }
114         |   STRUCT{ return sngcpp::ast::ClassKey::struct_; }
115         |   UNION{ return sngcpp::ast::ClassKey::union_; }
116         ;
117 
118     ClassName(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
119         ::= QualifiedIdNode(ctx):className{ return className; }
120         ;
121 
122     ClassVirtSpecifiers(var sngcpp::ast::Specifier specifiers) : sngcpp::ast::Specifier
123         ::= ((ClassVirtSpecifier:specifier{ specifiers = specifiers | specifier; })*)
124         {
125             return specifiers;
126         }
127         ;
128 
129     ClassVirtSpecifier : sngcpp::ast::Specifier
130         ::= FINAL{ return sngcpp::ast::Specifier::final_; }
131         |   EXPLICIT{ return sngcpp::ast::Specifier::explicit_; }
132         ;
133 
134     BaseClause(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
135         ::= COLON BaseClassSpecifierList(ctx):bc{ return bc; }
136         ;
137 
138     BaseClassSpecifierList(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr node, var Span s) : sngcpp::ast::Node*
139         ::=
140         (   BaseClassSpecifier(ctx):b1{ s = span; node.reset(b1); }
141             (COMMA BaseClassSpecifier(ctx):b2{ s.end = span.end; node.reset(new sngcpp::ast::BaseClassSpecifierSequenceNode(s, node.release(), b2)); })*
142         )
143         {
144             return node.release();
145         }
146         ;
147 
148     BaseClassSpecifier(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
149         ::= BaseSpecifiers:baseSpecifiers{ s = span; } ClassName(ctx):className
150         {
151             s.end = span.end; 
152             return new sngcpp::ast::BaseClassSpecifierNode(s, baseSpecifiers, className);
153         }
154         ;
155 
156     BaseSpecifiers(var sngcpp::ast::Specifier specifiers) : sngcpp::ast::Specifier
157         ::=
158         (
159             (BaseSpecifier:specifier{ specifiers = specifiers | specifier; })*
160         )
161         {
162             return specifiers;
163         }
164         ;
165 
166     BaseSpecifier : sngcpp::ast::Specifier
167         ::= VIRTUAL{ return sngcpp::ast::Specifier::virtual_; }
168         |   AccessSpecifier:accessSpecifier{ return accessSpecifier; }
169         ;
170 
171     AccessSpecifier : sngcpp::ast::Specifier
172         ::= PUBLIC{ return sngcpp::ast::Specifier::public_; }
173         |   PROTECTED{ return sngcpp::ast::Specifier::protected_; }
174         |   PRIVATE{ return sngcpp::ast::Specifier::private_; }
175         ;
176 
177     VirtPureSpecifiers(bool functionMember, var sngcpp::ast::Specifier specifiers) : sngcpp::ast::Specifier
178         ::=
179         (
180             (VirtSpecifier(functionMember):virtSpecifier{ specifiers = specifiers | virtSpecifier; })* (PureSpecifier(functionMember):pureSpecifier{ specifiers = specifiers | pureSpecifier; })?
181         )
182         {
183             return specifiers;
184         }
185         ;
186 
187     VirtSpecifier(bool functionMember, var sngcpp::ast::Specifier specifier) : sngcpp::ast::Specifier
188         ::=
189         (   OVERRIDE{ pass = functionMember; specifier = sngcpp::ast::Specifier::override_; }
190         |   FINAL{ pass = functionMember; specifier = sngcpp::ast::Specifier::final_; }
191         |   NEW{ pass = functionMember; specifier = sngcpp::ast::Specifier::new_; }
192         )
193         {
194             return specifier;
195         }
196         ;
197 
198     PureSpecifier(bool functionMember) : sngcpp::ast::Specifier
199         ::= (ASSIGN IntegerLiteral:integerLiteral{ pass = functionMember && integerLiteral->Value() == 0; })
200         {
201             return sngcpp::ast::Specifier::pure_;
202         }
203         ;
204 
205     SpecialMemberFunctionDefinition(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr declarator, var sngcpp::ast::Specifier defaultOrDeleteSpecifier, var Span s) : sngcpp::ast::Node*
206         ::= DeclSpecifiers:declSpecifiers{ s = span; } Declarator(ctx):d{ declarator.reset(d); pass = sngcpp::ast::IsFunctionDeclarator(declarator.get()); }
207             CtorInitializer(ctx):ctorInitializer?
208                 (   FunctionBody(ctx):body{ s.end = span.end; }
209                 |   ASSIGN (DEFAULT{ defaultOrDeleteSpecifier = sngcpp::ast::Specifier::default_; } | DELETE{ defaultOrDeleteSpecifier = sngcpp::ast::Specifier::delete_; }) SEMICOLON{ s.end = span.end; }
210                 )
211         {
212             return new sngcpp::ast::SpecialMemberFunctionNode(s, declSpecifiers | defaultOrDeleteSpecifier, declarator.release(), ctorInitializer, body);
213         }
214         ;
215 
216     CtorInitializer(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
217         ::= COLON{ s = span; } MemberInitializerList(ctx):mil{ s.end = span.end; return new sngcpp::ast::CtorInitializerNode(s, mil); }
218         ;
219 
220     MemberInitializerList(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr list) : sngcpp::ast::Node*
221         ::= (MemberInitializer(ctx):left{ list.reset(left); } (COMMA MemberInitializer(ctx):right{ list.reset(new sngcpp::ast::MemberInitializerSequenceNode(span, list.release(), right)); })*)
222         {
223             return list.release();
224         }
225         ;
226 
227     MemberInitializer(sngcpp::cppparser::ParsingContext* ctx, var Span s, var Span argsSpan) : sngcpp::ast::Node*
228         ::= (MemberInitializerId(ctx):id1{ s = span; } LPAREN{ argsSpan = span; } ArgumentList(ctx):args RPAREN{ argsSpan.end = span.end; })
229         {
230             s.end = span.end;
231             return new sngcpp::ast::MemberInitializerNode(s, id1, new sngcpp::ast::ExpressionListInitializerNode(argsSpan, args));
232         }
233         |   MemberInitializerId(ctx):id2{ s = span; } BracedInitializerList(ctx):bi
234         {
235             s.end = span.end;
236             return new sngcpp::ast::MemberInitializerNode(s, id2, bi);
237         }
238         ;
239 
240     MemberInitializerId(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
241         ::= QualifiedIdNode(ctx):qid{ return qid; }
242         ;
243 }