1
2
3
4
5
6 [hpp]#include <sngcm/cmparser/ParserApi.hpp>
7 [hpp]#include <sngcm/ast/Class.hpp>
8 [hpp]#include <sngcm/cmparser/ParsingContext.hpp>
9 [cpp]#include <sngcm/cmparser/Attribute.hpp>
10 [cpp]#include <sngcm/cmparser/Specifier.hpp>
11 [cpp]#include <sngcm/cmparser/Identifier.hpp>
12 [cpp]#include <sngcm/cmparser/TypeExpr.hpp>
13 [cpp]#include <sngcm/cmparser/Concept.hpp>
14 [cpp]#include <sngcm/cmparser/Expression.hpp>
15 [cpp]#include <sngcm/cmparser/Statement.hpp>
16 [cpp]#include <sngcm/cmparser/Parameter.hpp>
17 [cpp]#include <sngcm/cmparser/Function.hpp>
18 [cpp]#include <sngcm/cmparser/Template.hpp>
19 [cpp]#include <sngcm/cmparser/Typedef.hpp>
20 [cpp]#include <sngcm/cmparser/Enumeration.hpp>
21 [cpp]#include <sngcm/cmparser/Constant.hpp>
22 [cpp]#include <sngcm/cmparser/Delegate.hpp>
23 [cpp]#include <sngcm/cmlexer/CmajorLexer.hpp>
24 [cpp]#include <sngcm/cmlexer/CmajorTokens.hpp>
25
26 using namespace sngcm::ast;
27 using namespace CmajorTokens;
28
29 parser api(SNGCM_PARSER_API) ClassParser
30 {
31 uselexer CmajorLexer;
32
33 using AttributeParser.Attributes;
34 using SpecifierParser.Specifiers;
35 using IdentifierParser.Identifier;
36 using IdentifierParser.QualifiedId;
37 using TypeExprParser.TypeExpr;
38 using ConceptParser.WhereConstraint;
39 using ExpressionParser.ArgumentList;
40 using StatementParser.CompoundStatement;
41 using ParameterParser.ParameterList;
42 using FunctionParser.FunctionGroupId;
43 using TemplateParser.TemplateId;
44 using TemplateParser.TemplateParameterList;
45 using TypedefParser.Typedef;
46 using EnumerationParser.EnumType;
47 using ConstantParser.Constant;
48 using DelegateParser.Delegate;
49 using DelegateParser.ClassDelegate;
50
51 Class(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr cls, var Span s, var Span specifierSpan, var Span classSpan, var Span beginBraceSpan, var Span endBraceSpan) : ClassNode*
52 ::= empty{ s = span; } Attributes(moduleId):attrs? (Specifiers:specifiers{ specifierSpan = span; } - NEW) CLASS{ classSpan = span; } Identifier(moduleId):id
53 {
54 s.end = span.end;
55 cls.reset(new ClassNode(s, *moduleId, specifiers, id, attrs));
56 cls->SetSpecifierSpan(specifierSpan);
57 cls->SetClassSpan(classSpan);
58 }
59 TemplateParameterList(moduleId, ctx, cls.get()):templateParams?
60 InheritanceAndInterfaces(moduleId, ctx, cls.get()):inheritance?
61 (WhereConstraint(moduleId, ctx):constraint{ cls->SetConstraint(constraint); })?
62 LBRACE!{ beginBraceSpan = span; } ClassContent(moduleId, ctx, cls.get()):content RBRACE!
63 {
64 endBraceSpan = span;
65 cls->SetBeginBraceSpan(beginBraceSpan);
66 cls->SetEndBraceSpan(endBraceSpan);
67 return cls.release();
68 }
69 ;
70
71 InheritanceAndInterfaces(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::ClassNode* classNode)
72 ::= COLON
73 ( empty{ ctx->BeginParsingTypeExpr(); }
74 BaseClassOrInterface(moduleId, ctx):baseOrIntf{ classNode->AddBaseClassOrInterface(baseOrIntf); ctx->EndParsingTypeExpr(); } / { ctx->EndParsingTypeExpr(); }
75 ) % COMMA
76 ;
77
78 BaseClassOrInterface(boost::uuids::uuid* moduleId, ParsingContext* ctx) : Node*
79 ::= TemplateId(moduleId, ctx):templateId{ return templateId; }
80 | QualifiedId(moduleId):qid{ return qid; }
81 ;
82
83 ClassContent(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::ClassNode* classNode)
84 ::= (ClassMember(moduleId, ctx, classNode):classMember{ classNode->AddMember(classMember); })*
85 ;
86
87 ClassMember(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::ClassNode* classNode) : Node*
88 ::= StaticConstructor(moduleId, ctx, classNode):staticConstructor{ return staticConstructor; }
89 | Constructor(moduleId, ctx, classNode):constructor{ return constructor; }
90 | Destructor(moduleId, ctx, classNode):destructor{ return destructor; }
91 | MemberFunction(moduleId, ctx):memberFunction{ return memberFunction; }
92 | ConversionFunction(moduleId, ctx):conversionFunction{ return conversionFunction; }
93 | MemberVariable(moduleId, ctx):memberVariable{ return memberVariable; }
94 | Typedef(moduleId, ctx):typedefinition{ return typedefinition; }
95 | Class(moduleId, ctx):cls{ return cls; }
96 | EnumType(moduleId, ctx):enumType{ return enumType; }
97 | Constant(moduleId, ctx):constant{ return constant; }
98 | Delegate(moduleId, ctx):delegate{ return delegate; }
99 | ClassDelegate(moduleId, ctx):classDelegate{ return classDelegate; }
100 ;
101
102 StaticConstructor(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::ClassNode* classNode, var std::unique_ptr staticConstructor, var Span s, var Span specifierSpan,
103 var std::u32string className) : StaticConstructorNode*
104 ::=
105 ( empty{ s = span; } Attributes(moduleId):attrs? Specifiers:specifiers{ specifierSpan = span; } Identifier(moduleId):id{ className = lexer.GetMatch(span); } LPAREN RPAREN
106 {
107 s.end = span.end;
108 if (className != classNode->Id()->Str()) pass = false; else if (!StaticConstructorSpecifiers(specifiers)) pass = false; else
109 {
110 staticConstructor.reset(new StaticConstructorNode(s, *moduleId, specifiers, attrs));
111 staticConstructor->SetClassId(id);
112 staticConstructor->SetSpecifierSpan(specifierSpan);
113 }
114 }
115 (COLON (Initializer(moduleId, ctx):initializer{ staticConstructor->AddInitializer(initializer); } % COMMA))?
116 (WhereConstraint(moduleId, ctx):constraint{ staticConstructor->SetConstraint(constraint); })?
117 (CompoundStatement(moduleId, ctx):body{ staticConstructor->SetBody(body); } | SEMICOLON)
118 )
119 {
120 return staticConstructor.release();
121 }
122 ;
123
124 Constructor(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::ClassNode* classNode, var std::unique_ptr ctor, var Span s, var Span specifierSpan) : Node*
125 ::=
126 ( empty{ s = span; } Attributes(moduleId):attrs? Specifiers:specifiers{ specifierSpan = span; } Identifier(moduleId):id
127 {
128 std::u32string className = lexer.GetMatch(span);
129 s.end = span.end;
130 if (className != classNode->Id()->Str()) pass = false; else
131 {
132 ctor.reset(new ConstructorNode(s, *moduleId, specifiers, attrs));
133 ctor->SetClassId(id);
134 ctor->SetSpecifierSpan(specifierSpan);
135 }
136 }
137 ParameterList(moduleId, ctx, ctor.get()):paramList
138 (COLON (Initializer(moduleId, ctx):initializer{ ctor->AddInitializer(initializer); } % COMMA))?
139 (WhereConstraint(moduleId, ctx):constraint{ ctor->SetConstraint(constraint); })?
140 (CompoundStatement(moduleId, ctx):body{ ctor->SetBody(body); } | SEMICOLON)
141 )
142 {
143 return ctor.release();
144 }
145 ;
146
147 Destructor(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::ClassNode* classNode, var std::unique_ptr dtor, var Span s, var Span specifierSpan, var std::u32string className) : Node*
148 ::=
149 ( empty{ s = span; } Attributes(moduleId):attrs? Specifiers:specifiers{ specifierSpan = span; } CPL Identifier(moduleId):id{ className = lexer.GetMatch(span); } LPAREN! RPAREN!
150 {
151 s.end = span.end;
152 if (className != classNode->Id()->Str()) pass = false; else
153 {
154 dtor.reset(new DestructorNode(s, *moduleId, specifiers, attrs));
155 dtor->SetClassId(id);
156 dtor->SetSpecifierSpan(specifierSpan);
157 }
158 }
159 (WhereConstraint(moduleId, ctx):contraint{ dtor->SetConstraint(contraint); })?
160 (CompoundStatement(moduleId, ctx):body{ dtor->SetBody(body); } | SEMICOLON)
161 )
162 {
163 return dtor.release();
164 }
165 ;
166
167 Initializer(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr initializer) : InitializerNode*
168 ::=
169 ( THIS{ initializer.reset(new ThisInitializerNode(span, *moduleId)); } LPAREN! ArgumentList(moduleId, ctx, initializer.get()):thisArgs! RPAREN!
170 | BASE{ initializer.reset(new BaseInitializerNode(span, *moduleId)); } LPAREN! ArgumentList(moduleId, ctx, initializer.get()):baseArgs! RPAREN!
171 | Identifier(moduleId):id{ initializer.reset(new MemberInitializerNode(span, *moduleId, id)); } LPAREN! ArgumentList(moduleId, ctx, initializer.get()):memberArgs! RPAREN!
172 )
173 {
174 return initializer.release();
175 }
176 ;
177
178 MemberFunction(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr memFun, var Span s, var Span specifierSpan, var Span groupIdSpan) : Node*
179 ::=
180 ( empty{ s = span; } Attributes(moduleId):attrs? Specifiers:specifiers{ specifierSpan = span; } TypeExpr(moduleId, ctx):returnType FunctionGroupId(moduleId, ctx):groupId
181 {
182 s.end = span.end;
183 groupIdSpan = span;
184 memFun.reset(new MemberFunctionNode(s, *moduleId, specifiers, returnType, groupId, attrs));
185 memFun->SetSpecifierSpan(specifierSpan);
186 memFun->SetGroupIdSpan(groupIdSpan);
187 }
188 ParameterList(moduleId, ctx, memFun.get()):paramList (CONST{ memFun->SetConst(); })?
189 (WhereConstraint(moduleId, ctx):constraint{ memFun->SetConstraint(constraint); })?
190 (CompoundStatement(moduleId, ctx):body{ memFun->SetBody(body); } | SEMICOLON)
191 )
192 {
193 return memFun.release();
194 }
195 ;
196
197 ConversionFunction(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr conversionFun, var Span s, var Span specifierSpan) : Node*
198 ::=
199 ( empty{ s = span; } Attributes(moduleId):attrs? Specifiers:specifiers{ specifierSpan = span; } OPERATOR TypeExpr(moduleId, ctx):type LPAREN! RPAREN!
200 {
201 s.end = span.end;
202 conversionFun.reset(new ConversionFunctionNode(s, *moduleId, specifiers, type, attrs));
203 conversionFun->SetSpecifierSpan(specifierSpan);
204 }
205 (CONST{ conversionFun->SetConst(); })?
206 (WhereConstraint(moduleId, ctx):constraint{ conversionFun->SetConstraint(constraint); })?
207 (CompoundStatement(moduleId, ctx):body{ conversionFun->SetBody(body); } | SEMICOLON)
208 )
209 {
210 return conversionFun.release();
211 }
212 ;
213
214 MemberVariable(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s, var Span specifierSpan) : MemberVariableNode*
215 ::= empty{ s = span; } Attributes(moduleId):attrs? Specifiers:specifiers{ specifierSpan = span; } TypeExpr(moduleId, ctx):type Identifier(moduleId):id SEMICOLON
216 {
217 s.end = span.end;
218 MemberVariableNode* value = new MemberVariableNode(s, *moduleId, specifiers, type, id, attrs);
219 value->SetSpecifierSpan(specifierSpan);
220 return value;
221 }
222 ;
223 }