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(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:attrs? Specifiers:specifiers{ specifierSpan = span; } CLASS{ classSpan = span; } Identifier:id
53 {
54 s.end = span.end;
55 cls.reset(new ClassNode(s, specifiers, id, attrs));
56 cls->SetSpecifierSpan(specifierSpan);
57 cls->SetClassSpan(classSpan);
58 }
59 TemplateParameterList(ctx, cls.get()):templateParams?
60 InheritanceAndInterfaces(ctx, cls.get()):inheritance?
61 (WhereConstraint(ctx):constraint{ cls->SetConstraint(constraint); })?
62 LBRACE!{ beginBraceSpan = span; } ClassContent(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(ParsingContext* ctx, sngcm::ast::ClassNode* classNode)
72 ::= COLON
73 ( empty{ ctx->BeginParsingTypeExpr(); }
74 BaseClassOrInterface(ctx):baseOrIntf{ classNode->AddBaseClassOrInterface(baseOrIntf); ctx->EndParsingTypeExpr(); } / { ctx->EndParsingTypeExpr(); }
75 ) % COMMA
76 ;
77
78 BaseClassOrInterface(ParsingContext* ctx) : Node*
79 ::= TemplateId(ctx):templateId{ return templateId; }
80 | QualifiedId:qid{ return qid; }
81 ;
82
83 ClassContent(ParsingContext* ctx, sngcm::ast::ClassNode* classNode)
84 ::= (ClassMember(ctx, classNode):classMember{ classNode->AddMember(classMember); })*
85 ;
86
87 ClassMember(ParsingContext* ctx, sngcm::ast::ClassNode* classNode) : Node*
88 ::= StaticConstructor(ctx, classNode):staticConstructor{ return staticConstructor; }
89 | Constructor(ctx, classNode):constructor{ return constructor; }
90 | Destructor(ctx, classNode):destructor{ return destructor; }
91 | MemberFunction(ctx):memberFunction{ return memberFunction; }
92 | ConversionFunction(ctx):conversionFunction{ return conversionFunction; }
93 | MemberVariable(ctx):memberVariable{ return memberVariable; }
94 | Typedef(ctx):typedefinition{ return typedefinition; }
95 | Class(ctx):cls{ return cls; }
96 | EnumType(ctx):enumType{ return enumType; }
97 | Constant(ctx):constant{ return constant; }
98 | Delegate(ctx):delegate{ return delegate; }
99 | ClassDelegate(ctx):classDelegate{ return classDelegate; }
100 ;
101
102 StaticConstructor(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:attrs? Specifiers:specifiers{ specifierSpan = span; } Identifier: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, specifiers, attrs));
111 staticConstructor->SetClassId(id);
112 staticConstructor->SetSpecifierSpan(specifierSpan);
113 }
114 }
115 (COLON (Initializer(ctx):initializer{ staticConstructor->AddInitializer(initializer); } % COMMA))?
116 (WhereConstraint(ctx):constraint{ staticConstructor->SetConstraint(constraint); })?
117 (CompoundStatement(ctx):body{ staticConstructor->SetBody(body); } | SEMICOLON)
118 )
119 {
120 return staticConstructor.release();
121 }
122 ;
123
124 Constructor(ParsingContext* ctx, sngcm::ast::ClassNode* classNode, var std::unique_ptr ctor, var Span s, var Span specifierSpan) : Node*
125 ::=
126 ( empty{ s = span; } Attributes:attrs? Specifiers:specifiers{ specifierSpan = span; } Identifier: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, specifiers, attrs));
133 ctor->SetClassId(id);
134 ctor->SetSpecifierSpan(specifierSpan);
135 }
136 }
137 ParameterList(ctx, ctor.get()):paramList
138 (COLON (Initializer(ctx):initializer{ ctor->AddInitializer(initializer); } % COMMA))?
139 (WhereConstraint(ctx):constraint{ ctor->SetConstraint(constraint); })?
140 (CompoundStatement(ctx):body{ ctor->SetBody(body); } | SEMICOLON)
141 )
142 {
143 return ctor.release();
144 }
145 ;
146
147 Destructor(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:attrs? Specifiers:specifiers{ specifierSpan = span; } CPL Identifier: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, specifiers, attrs));
155 dtor->SetClassId(id);
156 dtor->SetSpecifierSpan(specifierSpan);
157 }
158 }
159 (WhereConstraint(ctx):contraint{ dtor->SetConstraint(contraint); })?
160 (CompoundStatement(ctx):body{ dtor->SetBody(body); } | SEMICOLON)
161 )
162 {
163 return dtor.release();
164 }
165 ;
166
167 Initializer(ParsingContext* ctx, var std::unique_ptr initializer) : InitializerNode*
168 ::=
169 ( THIS{ initializer.reset(new ThisInitializerNode(span)); } LPAREN! ArgumentList(ctx, initializer.get()):thisArgs! RPAREN!
170 | BASE{ initializer.reset(new BaseInitializerNode(span)); } LPAREN! ArgumentList(ctx, initializer.get()):baseArgs! RPAREN!
171 | Identifier:id{ initializer.reset(new MemberInitializerNode(span, id)); } LPAREN! ArgumentList(ctx, initializer.get()):memberArgs! RPAREN!
172 )
173 {
174 return initializer.release();
175 }
176 ;
177
178 MemberFunction(ParsingContext* ctx, var std::unique_ptr memFun, var Span s, var Span specifierSpan, var Span groupIdSpan) : Node*
179 ::=
180 ( empty{ s = span; } Attributes:attrs? Specifiers:specifiers{ specifierSpan = span; } TypeExpr(ctx):returnType FunctionGroupId(ctx):groupId
181 {
182 s.end = span.end;
183 groupIdSpan = span;
184 memFun.reset(new MemberFunctionNode(s, specifiers, returnType, groupId, attrs));
185 memFun->SetSpecifierSpan(specifierSpan);
186 memFun->SetGroupIdSpan(groupIdSpan);
187 }
188 ParameterList(ctx, memFun.get()):paramList (CONST{ memFun->SetConst(); })?
189 (WhereConstraint(ctx):constraint{ memFun->SetConstraint(constraint); })?
190 (CompoundStatement(ctx):body{ memFun->SetBody(body); } | SEMICOLON)
191 )
192 {
193 return memFun.release();
194 }
195 ;
196
197 ConversionFunction(ParsingContext* ctx, var std::unique_ptr conversionFun, var Span s, var Span specifierSpan) : Node*
198 ::=
199 ( empty{ s = span; } Attributes:attrs? Specifiers:specifiers{ specifierSpan = span; } OPERATOR TypeExpr(ctx):type LPAREN! RPAREN!
200 {
201 s.end = span.end;
202 conversionFun.reset(new ConversionFunctionNode(s, specifiers, type, attrs));
203 conversionFun->SetSpecifierSpan(specifierSpan);
204 }
205 (CONST{ conversionFun->SetConst(); })?
206 (WhereConstraint(ctx):constraint{ conversionFun->SetConstraint(constraint); })?
207 (CompoundStatement(ctx):body{ conversionFun->SetBody(body); } | SEMICOLON)
208 )
209 {
210 return conversionFun.release();
211 }
212 ;
213
214 MemberVariable(ParsingContext* ctx, var Span s, var Span specifierSpan) : MemberVariableNode*
215 ::= empty{ s = span; } Attributes:attrs? Specifiers:specifiers{ specifierSpan = span; } TypeExpr(ctx):type Identifier:id SEMICOLON
216 {
217 s.end = span.end;
218 MemberVariableNode* value = new MemberVariableNode(s, specifiers, type, id, attrs);
219 value->SetSpecifierSpan(specifierSpan);
220 return value;
221 }
222 ;
223 }