1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 [hpp]#include <sngcm/cmparser/ParserApi.hpp>
  7 [hpp]#include <sngcm/ast/Literal.hpp>
  8 [hpp]#include <sngcm/cmparser/ParsingContext.hpp>
  9 [cpp]#include <sngcm/cmparser/Expression.hpp>
 10 [cpp]#include <sngcm/cmlexer/CmajorLexer.hpp>
 11 [cpp]#include <sngcm/cmlexer/CmajorTokens.hpp>
 12 
 13 using namespace sngcm::ast;
 14 using namespace CmajorTokens;
 15 
 16 parser api(SNGCM_PARSER_API) LiteralParser
 17 {
 18     uselexer CmajorLexer;
 19 
 20     using ExpressionParser.Expression;
 21 
 22     Literal(boost::uuids::uuid* moduleId, ParsingContext* ctx) : LiteralNode*
 23         ::= SimpleLiteral(moduleId):simpleLiteral{ return simpleLiteral; }
 24         |   ComplexLiteral(moduleId, ctx):complexLiteral{ return complexLiteral; }
 25         ;
 26 
 27     SimpleLiteral(boost::uuids::uuid* moduleId) : LiteralNode*
 28         ::= TRUE
 29         {
 30             LiteralNode* value = new BooleanLiteralNode(span, *moduleId, true);
 31             value->SetText(lexer.GetMatch(span));
 32             return value;
 33         }
 34         |   FALSE
 35         {
 36             LiteralNode* value = new BooleanLiteralNode(span, *moduleId, false);
 37             value->SetText(lexer.GetMatch(span));
 38             return value;
 39         }
 40         |   FLOATINGLIT
 41         {
 42             ParseFloatingLiteral(lexer.FileName(), lexer.GetToken(pos), lexer.floatingLit, lexer.floatingLitFloat);
 43             LiteralNode* value = CreateFloatingLiteralNode(span, *moduleId, lexer.floatingLit, lexer.floatingLitFloat);
 44             value->SetText(lexer.GetMatch(span));
 45             return value;
 46         }
 47         |   INTLIT
 48         {
 49             ParseIntegerLiteral(lexer.FileName(), lexer.GetToken(pos), lexer.intLit, lexer.intLitUnsigned);
 50             LiteralNode* value = CreateIntegerLiteralNode(span, *moduleId, lexer.intLit, lexer.intLitUnsigned);
 51             value->SetText(lexer.GetMatch(span));
 52             return value;
 53         }
 54         |   CHARLIT
 55         {
 56             ParseCharacterLiteral(lexer.FileName(), lexer.GetToken(pos), lexer.chrLit, lexer.chrLitPrefix);
 57             LiteralNode* value = CreateCharacterLiteralNode(span, *moduleId, lexer.chrLit, lexer.chrLitPrefix);
 58             value->SetText(lexer.GetMatch(span));
 59             return value;
 60         }
 61         |   STRINGLIT
 62         {
 63             ParseStringLiteral(lexer.FileName(), lexer.GetToken(pos), lexer.strLit, lexer.strLitPrefix);
 64             LiteralNode* value = CreateStringLiteralNode(span, *moduleId, lexer.strLit, lexer.strLitPrefix);
 65             value->SetText(lexer.GetMatch(span));
 66             return value;
 67         }
 68         |   NULLLIT
 69         {
 70             LiteralNode* value = new NullLiteralNode(span, *moduleId);
 71             value->SetText(lexer.GetMatch(span));
 72             return value;
 73         }
 74         ;
 75 
 76     ComplexLiteral(boost::uuids::uuid* moduleId, ParsingContext* ctx) : LiteralNode*
 77         ::= ArrayLiteral(moduleId, ctx):arrayLiteral{ return arrayLiteral; }
 78         |   StructuredLiteral(moduleId, ctx):structuredLiteral{ return structuredLiteral; }
 79         ;
 80 
 81     ArrayLiteral(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr arrayLiteral) : ArrayLiteralNode*
 82         ::= LBRACKET{ arrayLiteral.reset(new ArrayLiteralNode(span, *moduleId)); } (Expression(moduleId, ctx):expr{ arrayLiteral->AddValue(expr); } % COMMA)? RBRACKET!
 83         {
 84             arrayLiteral->SetSpanEnd(span.end);
 85             return arrayLiteral.release();
 86         }
 87         ;
 88 
 89     StructuredLiteral(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr structuredLiteral) : StructuredLiteralNode*
 90         ::= LBRACE{ structuredLiteral.reset(new StructuredLiteralNode(span, *moduleId)); } (Expression(moduleId, ctx):expr{ structuredLiteral->AddMember(expr); } % COMMA)? RBRACE!
 91         {
 92             structuredLiteral->SetSpanEnd(span.end);
 93             return structuredLiteral.release();
 94         }
 95         ;
 96 
 97     ruleinfo
 98     {
 99         (Literal, "literal"), (SimpleLiteral, "simple literal"), (ComplexLiteral, "complex literal"), (ArrayLiteral, "array literal"), (StructuredLiteral, "structured literal")
100     }
101 }