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