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/Function.hpp>
 9 [cpp]#include <sngcpp/parser/Class.hpp>
10 [cpp]#include <sngcpp/parser/Declaration.hpp>
11 [cpp]#include <sngcpp/parser/Declarator.hpp>
12 [cpp]#include <sngcpp/parser/Statement.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) FunctionParser
21 {
22     uselexer CppLexer;
23 
24     using ClassParser.VirtPureSpecifiers;
25     using DeclarationParser.DeclSpecifiers;
26     using DeclaratorParser.Declarator;
27     using StatementParser.CompoundStatement;
28     using TypeExprParser.TypeExpr;
29 
30     FunctionDefinition(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr declarator, var sngcpp::ast::Specifier defaultOrDeleteSpecifier, var Span s) : sngcpp::ast::Node*
31         ::= DeclSpecifiers:declSpecifiers{ s = span; } TypeExpr(ctx):typeExpr Declarator(ctx):d{ declarator.reset(d); pass = sngcpp::ast::IsFunctionDeclarator(declarator.get()); }
32             VirtPureSpecifiers(true):virtPureSpecifiers
33                     (   FunctionBody(ctx):body{ s.end = span.end; }
34                     |   ASSIGN (DEFAULT{ defaultOrDeleteSpecifier = sngcpp::ast::Specifier::default_; } | DELETE{ defaultOrDeleteSpecifier = sngcpp::ast::Specifier::delete_; }) SEMICOLON{ s.end = span.end; }
35                     |   SEMICOLON{ s.end = span.end; pass = sngcpp::ast::HasPureSpecifier(virtPureSpecifiers); }
36                     ) 
37             {
38                 return new sngcpp::ast::FunctionNode(s, declSpecifiers | defaultOrDeleteSpecifier | virtPureSpecifiers, typeExpr, declarator.release(), body);
39             }
40         ;
41 
42     FunctionBody(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::CompoundStatementNode*
43         ::= empty{ ctx->BeginFunctionBody(); } CompoundStatement(ctx):body{ ctx->EndFunctionBody(); return body; } / { ctx->EndFunctionBody(); }
44         ;
45 
46     ParameterList(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr param, var Span s) : sngcpp::ast::Node* 
47         ::= LPAREN{ s = span; }
48             (   ParameterDeclaration(ctx):left{ param.reset(left); }
49                 (COMMA ParameterDeclaration(ctx):right{ s.end = span.end; param.reset(new sngcpp::ast::ParameterSequenceNode(s, param.release(), right)); })*
50             )?
51             RPAREN{ s.end = span.end; return param.release(); }
52         ;
53 
54     ParameterDeclaration(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
55         ::= (TypeExpr(ctx):typeExpr{ s = span; } (Declarator(ctx):declarator{ s.end = span.end; })?){ return new sngcpp::ast::ParameterNode(s, typeExpr, declarator); }
56         ;
57 }