1
2
3
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 }