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 }