1
2
3
4
5
6 [hpp]#include <sngcm/cmparser/ParserApi.hpp>
7 [hpp]#include <sngcm/ast/Concept.hpp>
8 [hpp]#include <sngcm/cmparser/ParsingContext.hpp>
9 [cpp]#include <sngcm/cmparser/Parameter.hpp>
10 [cpp]#include <sngcm/cmparser/Specifier.hpp>
11 [cpp]#include <sngcm/cmparser/TypeExpr.hpp>
12 [cpp]#include <sngcm/cmparser/Identifier.hpp>
13 [cpp]#include <sngcm/cmparser/Expression.hpp>
14 [cpp]#include <sngcm/cmparser/Function.hpp>
15 [cpp]#include <sngcm/cmlexer/CmajorLexer.hpp>
16 [cpp]#include <sngcm/cmlexer/CmajorTokens.hpp>
17
18 using namespace sngcm::ast;
19 using namespace CmajorTokens;
20
21 parser api(SNGCM_PARSER_API) ConceptParser
22 {
23 uselexer CmajorLexer;
24
25 using SpecifierParser.Specifiers;
26 using IdentifierParser.Identifier;
27 using IdentifierParser.QualifiedId;
28 using ParameterParser.ParameterList;
29 using ExpressionParser.Expression;
30 using ExpressionParser.InvokeExpr;
31 using TypeExprParser.TypeExpr;
32 using FunctionParser.FunctionGroupId;
33
34 Concept(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr conceptNode, var std::unique_ptr constraint,
35 var Span s, var Span beginBraceSpan, var Span endBraceSpan) : ConceptNode*
36 ::= empty{ ctx->BeginParsingConcept(); }
37 ( (Specifiers:specifiers{ s = span; } CONCEPT Identifier(moduleId):conceptName!){ conceptNode.reset(new ConceptNode(span, *moduleId, specifiers, conceptName)); }
38 LANGLE! (Identifier(moduleId):typeParam{ conceptNode->AddTypeParameter(typeParam); } % COMMA) RANGLE!
39 ((Refinement(moduleId):refinement{ conceptNode->SetRefinement(refinement); })?
40 (WhereConstraint(moduleId, ctx):c{ s.end = span.end; constraint.reset(c); constraint->SetHeaderConstraint(); conceptNode->AddConstraint(constraint.release()); })?){ conceptNode->SetSpan(s); }
41 LBRACE!{ beginBraceSpan = span; } ConceptBody(moduleId, ctx, conceptNode.get()):body! RBRACE!{ endBraceSpan = span; }
42 )
43 {
44 ctx->EndParsingConcept();
45 conceptNode->SetBeginBraceSpan(beginBraceSpan);
46 conceptNode->SetEndBraceSpan(endBraceSpan);
47 return conceptNode.release();
48 }
49 /
50 {
51 ctx->EndParsingConcept();
52 }
53 ;
54
55 Refinement(boost::uuids::uuid* moduleId, var std::unique_ptr conceptId) : ConceptIdNode*
56 ::= (COLON QualifiedId(moduleId):refinedConcept{ conceptId.reset(new ConceptIdNode(span, *moduleId, refinedConcept)); }
57 LANGLE! (Identifier(moduleId):typeParam{ conceptId->AddTypeParameter(typeParam); } % COMMA) RANGLE!){ return conceptId.release(); }
58 ;
59
60
61 ConceptBody(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::ConceptNode* conceptNode)
62 ::= (ConceptBodyConstraint(moduleId, ctx, conceptNode):bodyConstraint | Axiom(moduleId, ctx, conceptNode):axiom)*
63 ;
64
65 ConceptBodyConstraint(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::ConceptNode* conceptNode)
66 ::= TypeNameConstraint(moduleId, ctx):typeNameConstraint{ conceptNode->AddConstraint(typeNameConstraint); }
67 | SignatureConstraint(moduleId, ctx, conceptNode->TypeParameters()[0]):signatureConstraint{ conceptNode->AddConstraint(signatureConstraint); }
68 | EmbeddedConstraint(moduleId, ctx):embeddedConstraint{ conceptNode->AddConstraint(embeddedConstraint); }
69 ;
70
71 TypeNameConstraint(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : ConstraintNode*
72 ::= TYPENAME{ s = span; } TypeExpr(moduleId, ctx):type! SEMICOLON!{ s.end = span.end; return new TypeNameConstraintNode(s, *moduleId, type); }
73 ;
74
75 SignatureConstraint(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::IdentifierNode* firstTypeParameter) : ConstraintNode*
76 ::= ConstructorConstraint(moduleId, ctx, firstTypeParameter):constructorConstraint{ return constructorConstraint; }
77 | DestructorConstraint(moduleId, ctx, firstTypeParameter):destructorConstraint{ return destructorConstraint; }
78 | MemberFunctionConstraint(moduleId, ctx):memberFunctionConstraint{ return memberFunctionConstraint; }
79 | FunctionConstraint(moduleId, ctx):functionConstraint{ return functionConstraint; }
80 ;
81
82 ConstructorConstraint(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::IdentifierNode* firstTypeParameter, var std::unique_ptr ctorConstraint, var Span e) : ConstraintNode*
83 ::= (EXPLICIT? Identifier(moduleId):id{ std::u32string className = lexer.GetMatch(span); pass = className == firstTypeParameter->Str(); if (pass) ctorConstraint.reset(new ConstructorConstraintNode(span, *moduleId, id)); }
84 ParameterList(moduleId, ctx, ctorConstraint.get()):paramList SEMICOLON!{ e = span; }){ ctorConstraint->SetSpanEnd(e.end); return ctorConstraint.release(); }
85 ;
86
87 DestructorConstraint(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::IdentifierNode* firstTypeParameter, var Span s) : ConstraintNode*
88 ::= (CPL{ s = span; } Identifier(moduleId):id{ std::u32string className = lexer.GetMatch(span); pass = className == firstTypeParameter->Str(); } LPAREN! RPAREN! SEMICOLON!{ s.end = span.end; })
89 {
90 return new DestructorConstraintNode(s, *moduleId, id);
91 }
92 ;
93
94 MemberFunctionConstraint(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr memberFunctionConstraint) : ConstraintNode*
95 ::= (TypeExpr(moduleId, ctx):returnType Identifier(moduleId):typeParam DOT FunctionGroupId(moduleId, ctx):functionGroupId!){ memberFunctionConstraint.reset(new MemberFunctionConstraintNode(span, *moduleId, returnType, typeParam, functionGroupId)); }
96 ParameterList(moduleId, ctx, memberFunctionConstraint.get()):paramList! SEMICOLON!{ memberFunctionConstraint->SetSpanEnd(span.end); return memberFunctionConstraint.release(); }
97 ;
98
99 FunctionConstraint(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr functionConstraint) : ConstraintNode*
100 ::= (TypeExpr(moduleId, ctx):returnType FunctionGroupId(moduleId, ctx):functionGroupId!){ functionConstraint.reset(new FunctionConstraintNode(span, *moduleId, returnType, functionGroupId)); }
101 ParameterList(moduleId, ctx, functionConstraint.get()):paramList! SEMICOLON!{ functionConstraint->SetSpanEnd(span.end); return functionConstraint.release(); }
102 ;
103
104 EmbeddedConstraint(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr constraint) : WhereConstraintNode*
105 ::= (WhereConstraint(moduleId, ctx):c SEMICOLON!){ constraint.reset(c); constraint->SetSemicolon(); return constraint.release(); }
106 ;
107
108 WhereConstraint(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : WhereConstraintNode*
109 ::= WHERE{ s = span; } ConstraintExpr(moduleId, ctx):constraint!{ s.end = span.end; return new WhereConstraintNode(s, *moduleId, constraint); }
110 ;
111
112 ConstraintExpr(boost::uuids::uuid* moduleId, ParsingContext* ctx) : ConstraintNode*
113 ::= DisjunctiveConstraintExpr(moduleId, ctx):disjunctiveConstraint{ return disjunctiveConstraint; }
114 ;
115
116 DisjunctiveConstraintExpr(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s, var std::unique_ptr constraint) : ConstraintNode*
117 ::=
118 ( ConjunctiveConstraintExpr(moduleId, ctx):left{ constraint.reset(left); s = span; }
119 ( OR ConjunctiveConstraintExpr(moduleId, ctx):right{ s.end = span.end; constraint.reset(new DisjunctiveConstraintNode(s, *moduleId, constraint.release(), right)); })*
120 )
121 {
122 return constraint.release();
123 }
124 ;
125
126 ConjunctiveConstraintExpr(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s, var std::unique_ptr constraint) : ConstraintNode*
127 ::=
128 ( PrimaryConstraintExpr(moduleId, ctx):left{ constraint.reset(left); s = span; }
129 ( AND PrimaryConstraintExpr(moduleId, ctx):right{ s.end = span.end; constraint.reset(new ConjunctiveConstraintNode(s, *moduleId, constraint.release(), right)); })*
130 )
131 {
132 return constraint.release();
133 }
134 ;
135
136 PrimaryConstraintExpr(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : ConstraintNode*
137 ::= LPAREN{ s = span; } ConstraintExpr(moduleId, ctx):constraint RPAREN!{ s.end = span.end; return new ParenthesizedConstraintNode(s, *moduleId, constraint); }
138 | AtomicConstraintExpr(moduleId, ctx):atomicConstraint{ return atomicConstraint; }
139 ;
140
141 AtomicConstraintExpr(boost::uuids::uuid* moduleId, ParsingContext* ctx) : ConstraintNode*
142 ::= PredicateConstraint(moduleId, ctx):predicateConstraint{ return predicateConstraint; }
143 | IsConstraint(moduleId, ctx):isConstraint{ return isConstraint; }
144 | MultiParamConstraint(moduleId, ctx):multiParamConstraint{ return multiParamConstraint; }
145 ;
146
147 PredicateConstraint(boost::uuids::uuid* moduleId, ParsingContext* ctx) : ConstraintNode*
148 ::= InvokeExpr(moduleId, ctx):invokeExpr{ return new PredicateConstraintNode(span, *moduleId, invokeExpr); }
149 ;
150
151 IsConstraint(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : ConstraintNode*
152 ::= TypeExpr(moduleId, ctx):type{ s = span; } IS ConceptOrTypeName(moduleId, ctx):conceptOrTypeName!{ s.end = span.end; return new IsConstraintNode(s, *moduleId, type, conceptOrTypeName); }
153 ;
154
155 ConceptOrTypeName(boost::uuids::uuid* moduleId, ParsingContext* ctx) : Node*
156 ::= TypeExpr(moduleId, ctx):conceptOrTypeName{ return conceptOrTypeName; }
157 ;
158
159 MultiParamConstraint(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr constraint) : ConstraintNode*
160 ::= QualifiedId(moduleId):id{ constraint.reset(new MultiParamConstraintNode(span, *moduleId, id)); }
161 LANGLE (TypeExpr(moduleId, ctx):typeExpr{ constraint->AddTypeExpr(typeExpr); } % COMMA) RANGLE!{ constraint->SetSpanEnd(span.end); return constraint.release(); }
162 ;
163
164 Axiom(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::ConceptNode* conceptNode, var std::unique_ptr axiomNode, var Span axiomSpan, var Span beginBraceSpan, var Span endBraceSpan)
165 ::=
166 ( AXIOM{ axiomSpan = span; } Identifier(moduleId):id? empty{ axiomNode.reset(new AxiomNode(axiomSpan, *moduleId, id)); }
167 ParameterList(moduleId, ctx, axiomNode.get()):paramList?
168 LBRACE!{ beginBraceSpan = span; } AxiomBody(moduleId, ctx, axiomNode.get()):axiomBody! RBRACE!{ endBraceSpan = span; }
169 )
170 {
171 axiomNode->SetBeginBraceSpan(beginBraceSpan);
172 axiomNode->SetEndBraceSpan(endBraceSpan);
173 conceptNode->AddAxiom(axiomNode.release());
174 }
175 ;
176
177 AxiomBody(boost::uuids::uuid* moduleId, ParsingContext* ctx, sngcm::ast::AxiomNode* axiom)
178 ::= (AxiomStatement(moduleId, ctx):stmt{ axiom->AddStatement(stmt); })*
179 ;
180
181 AxiomStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : AxiomStatementNode*
182 ::= (Expression(moduleId, ctx):expr{ s = span; } SEMICOLON!{ s.end = span.end; }){ return new AxiomStatementNode(s, *moduleId, expr, lexer.GetMatch(s)); }
183 ;
184
185 ruleinfo
186 {
187 (Concept, "conceptNode"), (Refinement, "refinement"), (ConceptBody, "concept body"), (ConceptBodyConstraint, "concept body constraint"), (TypeNameConstraint, "type name constraint"),
188 (SignatureConstraint, "signature constraint"), (ConstructorConstraint, "constructor constraint"), (DestructorConstraint, "destructor constraint"),
189 (MemberFunctionConstraint, "member function constraint"), (FunctionConstraint, "function constraint"), (EmbeddedConstraint, "embedded constraint"),
190 (WhereConstraint, "where constraint"), (ConstraintExpr, "constraint expression"), (DisjunctiveConstraintExpr, "disjunctive constraint expression"),
191 (ConjunctiveConstraintExpr, "conjunctive constraint expression"), (PrimaryConstraintExpr, "primary constraint expression"), (AtomicConstraintExpr, "atomic constraint expression"),
192 (PredicateConstraint, "preficate constraint"), (IsConstraint,"is constraint"), (ConceptOrTypeName, "concept or type name"), (MultiParamConstraint, "multiparameter constraint"),
193 (Axiom, "axiom"), (AxiomBody, "axiom body"), (AxiomStatement, "axiom statement")
194 }
195
196 }