1
2
3
4
5
6 [hpp]#include <sngcm/cmparser/ParserApi.hpp>
7 [hpp]#include <sngcm/ast/Enumeration.hpp>
8 [hpp]#include <sngcm/cmparser/ParsingContext.hpp>
9 [cpp]#include <sngcm/cmparser/Specifier.hpp>
10 [cpp]#include <sngcm/cmparser/Identifier.hpp>
11 [cpp]#include <sngcm/cmparser/TypeExpr.hpp>
12 [cpp]#include <sngcm/cmparser/Expression.hpp>
13 [cpp]#include <sngcm/cmlexer/CmajorLexer.hpp>
14 [cpp]#include <sngcm/cmlexer/CmajorTokens.hpp>
15
16 using namespace sngcm::ast;
17 using namespace CmajorTokens;
18
19 parser api(SNGCM_PARSER_API) EnumerationParser
20 {
21 uselexer CmajorLexer;
22
23 using SpecifierParser.Specifiers;
24 using IdentifierParser.Identifier;
25 using TypeExprParser.TypeExpr;
26 using ExpressionParser.Expression;
27
28 EnumType(ParsingContext* ctx, var std::unique_ptr enumTypeNode, var Span s, var Span beginBraceSpan, var Span endBraceSpan) : EnumTypeNode*
29 ::= Specifiers:specifiers{ s = span; } ENUM Identifier:enumTypeId!{ s.end = span.end; enumTypeNode.reset(new EnumTypeNode(s, specifiers, enumTypeId)); }
30 (UnderlyingType(ctx):underlyingType{ enumTypeNode->SetUnderlyingType(underlyingType); })?
31 LBRACE!{ beginBraceSpan = span; } EnumConstants(ctx, enumTypeNode.get()):enumConstants RBRACE!
32 {
33 endBraceSpan = span;
34 enumTypeNode->SetBeginBraceSpan(beginBraceSpan);
35 enumTypeNode->SetEndBraceSpan(endBraceSpan);
36 return enumTypeNode.release();
37 }
38 ;
39
40 UnderlyingType(ParsingContext* ctx) : Node*
41 ::= COLON TypeExpr(ctx):type{ return type; }
42 ;
43
44 EnumConstants(ParsingContext* ctx, sngcm::ast::EnumTypeNode* enumType)
45 ::= EnumConstant(ctx, enumType):enumConstant!{ enumType->AddConstant(enumConstant); } % COMMA
46 ;
47
48 EnumConstant(ParsingContext* ctx, sngcm::ast::EnumTypeNode* enumType, var Span s, var std::unique_ptr expr) : EnumConstantNode*
49 ::= Identifier:constantId!{ s = span; }
50 ( ASSIGN Expression(ctx):constantValue
51 {
52 expr.reset(constantValue);
53 expr->SetFullSpan();
54 Span v = expr->GetSpan();
55 s.end = expr->GetSpan().end;
56 EnumConstantNode* value = new EnumConstantNode(s, constantId, expr.release());
57 value->SetHasValue();
58 value->SetStrValue(lexer.GetMatch(v));
59 return value;
60 }
61 | empty{ return new EnumConstantNode(s, constantId, MakeNextEnumConstantValue(s, enumType)); }
62 )
63 ;
64
65 ruleinfo
66 {
67 (EnumType, "enumerated type"), (UnderlyingType, "underlying type"), (EnumConstants, "enumeration constants"), (EnumConstant, "enumeration constant")
68 }
69 }