1
2
3
4
5
6 [hpp]#include <sngcpp/parser/ParserApi.hpp>
7 [hpp]#include <sngcpp/parser/ParsingContext.hpp>
8 [hpp]#include <sngcpp/ast/Enumeration.hpp>
9 [cpp]#include <sngcpp/parser/Expression.hpp>
10 [cpp]#include <sngcpp/parser/Identifier.hpp>
11 [cpp]#include <sngcpp/parser/TypeExpr.hpp>
12 [cpp]#include <sngcpp/lexer/CppLexer.hpp>
13 [cpp]#include <sngcpp/lexer/CppTokens.hpp>
14
15 using namespace CppTokens;
16 using namespace soulng::lexer;
17
18 parser api(SNGCPP_PARSER_API) EnumerationParser
19 {
20 uselexer CppLexer;
21
22 using IdentifierParser.Identifier;
23 using IdentifierParser.QualifiedIdNode;
24 using TypeExprParser.TypeExpr;
25 using ExpressionParser.ConstantExpression;
26
27 EnumDeclaration(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
28 ::= EnumSpecifier(ctx):enumSpecifier SEMICOLON{ return enumSpecifier; }
29 ;
30
31 EnumSpecifier(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr enumTypeNode, var Span openBraceSpan, var Span closeBraceSpan) : sngcpp::ast::Node*
32 ::= (EnumHead(ctx):enumHead{ enumTypeNode.reset(enumHead); } LBRACE{ openBraceSpan = span; } Enumerators(ctx, enumTypeNode.get()):enumerators RBRACE!{ closeBraceSpan = span; })
33 {
34 enumTypeNode->SetOpenBraceSpan(openBraceSpan);
35 enumTypeNode->SetCloseBraceSpan(closeBraceSpan);
36 return enumTypeNode.release();
37 }
38 ;
39
40 EnumHead(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::EnumTypeNode*
41 ::= (EnumKey:enumKey{ s = span; } EnumName(ctx):enumName{ s.end = span.end; } (EnumBase(ctx):enumBase{ s.end = span.end; })?)
42 {
43 return new sngcpp::ast::EnumTypeNode(s, enumKey, enumName, enumBase);
44 }
45 ;
46
47 OpaqueEnumDeclaration(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
48 ::= EnumKey:enumKey{ s = span; } EnumName(ctx):enumName (EnumBase(ctx):enumBase)? SEMICOLON
49 {
50 s.end = span.end;
51 return new sngcpp::ast::EnumTypeNode(s, enumKey, enumName, enumBase);
52 }
53 ;
54
55 EnumKey : sngcpp::ast::EnumKey
56 ::= ENUM CLASS{ return sngcpp::ast::EnumKey::enumClass_; }
57 | ENUM STRUCT { return sngcpp::ast::EnumKey::enumStruct_; }
58 | ENUM{ return sngcpp::ast::EnumKey::enum_; }
59 ;
60
61 EnumName(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
62 ::= QualifiedIdNode(ctx):enumName{ return enumName; }
63 ;
64
65 EnumBase(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
66 ::= COLON TypeExpr(ctx):typeExpr{ return typeExpr; }
67 ;
68
69 Enumerators(sngcpp::cppparser::ParsingContext* ctx, sngcpp::ast::EnumTypeNode* enumTypeNode, var Span s)
70 ::=
71 ( EnumeratorDefinition(ctx):left{ s = span; enumTypeNode->AddEnumerator(s, left); }
72 (COMMA EnumeratorDefinition(ctx):right{ s.end = span.end; enumTypeNode->AddEnumerator(s, right); })*
73 )?
74 ;
75
76 EnumeratorDefinition(sngcpp::cppparser::ParsingContext* ctx, var Span s, var Span assignmentSpan, var std::u32string valueStr, var std::unique_ptr value) : sngcpp::ast::EnumeratorNode*
77 ::= (Enumerator:enumerator{ s = span; }
78 ( ASSIGN{ assignmentSpan = span; } ConstantExpression(ctx):expr{ value.reset(expr); value->SetFullSpan(); valueStr = lexer.GetMatch(value->GetSpan()); s.end = value->GetSpan().end; })?)
79 {
80 return new sngcpp::ast::EnumeratorNode(s, enumerator, value.release(), valueStr);
81 }
82 ;
83
84 Enumerator : std::u32string
85 ::= Identifier:id{ return id; }
86 ;
87 }