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 [cpp]#include <sngcpp/parser/Function.hpp>
 9 [cpp]#include <sngcpp/parser/Identifier.hpp>
10 [cpp]#include <sngcpp/parser/Expression.hpp>
11 [cpp]#include <sngcpp/parser/TypeExpr.hpp>
12 [cpp]#include <sngcpp/lexer/CppLexer.hpp>
13 [cpp]#include <sngcpp/lexer/CppTokens.hpp>
14 
15 using namespace CppTokens;
16 using namespace soulng::lexer;
17 
18 parser api(SNGCPP_PARSER_API) DeclaratorParser
19 {
20     uselexer CppLexer;
21 
22     using IdentifierParser.Identifier;
23     using IdentifierParser.NestedNameSpecifier;
24     using ExpressionParser.AssignmentExpression;
25     using ExpressionParser.ConstantExpression;
26     using ExpressionParser.IdExpression;
27     using ExpressionParser.ExpressionList;
28     using FunctionParser.ParameterList;
29     using TypeExprParser.CVSpecifierSequence;
30 
31     InitDeclarator(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node* 
32         ::= Declarator(ctx):declarator{ s = span; }
33             (   Initializer(ctx):initializer{ s.end = span.end; return new sngcpp::ast::InitDeclaratorNode(s, declarator, initializer); }
34             |   empty{ return declarator; }
35             )
36         ;
37 
38     Declarator(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr node, var Span s) : sngcpp::ast::Node*
39         ::=
40         (
41             (   IdExpression(ctx):idExpr{ node.reset(new sngcpp::ast::IdDeclaratorNode(span, idExpr)); s = span; }
42             |   (LPAREN{ s = span; } STAR Identifier:id1 RPAREN{ s.end = span.end; node.reset(new sngcpp::ast::FunctionPtrIdNode(s, id1)); })
43             |   (LPAREN{ s = span; } NestedNameSpecifier(ctx):nns{ node.reset(nns); } STAR Identifier:id2 RPAREN{ s.end = span.end; node.reset(new sngcpp::ast::MemberFunctionPtrIdNode(s, node.release(), id2)); })
44             )
45                 (   empty{ pass = !ctx->InFunctionBody(); } ParameterList(ctx):params CVSpecifierSequence:cvseq{ s.end = span.end; node.reset(new sngcpp::ast::FunctionDeclaratorNode(s, node.release(), params, cvseq)); }
46                 |   (LBRACKET ConstantExpression(ctx):size? RBRACKET!{ s.end = span.end; node.reset(new sngcpp::ast::ArrayDeclaratorNode(s, node.release(), size)); })*
47                 )
48         )
49         {
50             return node.release();
51         }
52         ;
53 
54     Initializer(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
55         ::= ASSIGN{ s = span; } InitializerClause(ctx):ic{ s.end = span.end; return new sngcpp::ast::AssignmentInitializerNode(s, ic); }
56         |   LPAREN{ s = span; } ExpressionList(ctx):exprs RPAREN{ s.end = span.end; return new sngcpp::ast::ExpressionListInitializerNode(s, exprs); }
57         |   BracedInitializerList(ctx):bi{ return bi; }
58         ;
59 
60     BraceOrEqualInitializer(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
61         ::= ASSIGN{ s = span; } InitializerClause(ctx):ic{ s.end = span.end; return new sngcpp::ast::AssignmentInitializerNode(s, ic); }
62         |   BracedInitializerList(ctx):bi{ return bi; }
63         ;
64 
65     BracedInitializerList(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr node, var Span s) : sngcpp::ast::Node*
66         ::= LBRACE{ s = span; node.reset(new sngcpp::ast::BracedInitializerListNode(s)); }
67             (InitializerClause(ctx):left{ s.end = span.end; node->AddInitializer(s, left); } (COMMA InitializerClause(ctx):right{ s.end = span.end; node->AddInitializer(s, right); })*)?
68             RBRACE{ node->SetEndBraceSpan(span); node->SetSpanEnd(span.end); return node.release(); }
69         ;
70 
71     InitializerClause(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node* 
72         ::= AssignmentExpression(ctx):expr{ return new sngcpp::ast::ExpressionInitializerNode(span, expr); }
73         |   BracedInitializerList(ctx):bi{ return bi; }
74         ;
75 
76     InitializerList(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr node, var Span s) : sngcpp::ast::Node*
77         ::= (InitializerClause(ctx):left{ s = span; node.reset(left); } (COMMA InitializerClause(ctx):right{ s.end = span.end; node.reset(new sngcpp::ast::ExpressionSequenceNode(s, node.release(), right)); })*)
78         {
79             return node.release();
80         }
81         ;
82 }