1 module gamma.parsgen.lalr1.LRItem;
2 
3 import gamma.grammar.Alternative;
4 import gamma.grammar.Symbol;
5 import gamma.grammar.SymbolNode;
6 import gamma.util.Indexed;
7 
8 class LRItem : Indexed
9 {
10     const size_t index_;
11 
12     Alternative alt;
13 
14     const bool altIsInContinuationGrammar;
15 
16     const size_t dotPos;
17 
18     const bool complete;
19 
20     Symbol symbolBehindDot;
21 
22     Symbol symbolPrecedingDot;
23 
24     LRItem nextItem;
25 
26     this(size_t index, Alternative alt, bool altIsInContinuationGrammar, size_t dotPos, LRItem nextItem)
27     {
28         this.index_ = index;
29         this.alt = alt;
30         this.altIsInContinuationGrammar = altIsInContinuationGrammar;
31         this.dotPos = dotPos;
32         this.complete = (dotPos == alt.rhs.length);
33 
34         if (!this.complete)
35             this.symbolBehindDot = (cast(SymbolNode) alt.rhs[dotPos]).symbol;
36 
37         if (dotPos > 0)
38             this.symbolPrecedingDot = (cast(SymbolNode) alt.rhs[dotPos - 1]).symbol;
39 
40         this.nextItem = nextItem;
41     }
42 
43     public override string toString()
44     {
45         import std.array : appender;
46 
47         auto writer = appender!string;
48 
49         writer.put(this.alt.lhs.symbol.toString);
50         if (this.altIsInContinuationGrammar)
51             writer.put(" =>");
52         else
53             writer.put(" ->");
54         foreach (i; 0 .. this.dotPos)
55         {
56             writer.put(' ');
57             writer.put((cast(SymbolNode) this.alt.rhs[i]).symbol.toString);
58         }
59         writer.put(" .");
60         foreach (i; this.dotPos .. this.alt.rhs.length)
61         {
62             writer.put(' ');
63             writer.put((cast(SymbolNode) this.alt.rhs[i]).symbol.toString);
64         }
65         return writer[];
66     }
67 
68     /**
69      * @see gamma.util.Indexed#index()
70      */
71     public size_t index() const
72     {
73         return this.index_;
74     }
75 }