1 2 // Copyright Tim Schendekehl 2023. 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // https://www.boost.org/LICENSE_1_0.txt) 6 7 module dparsergen.core.parsestackelem; 8 9 /** 10 Value for nonterminal or token with start location stored on parse stack. 11 */ 12 struct ParseStackElem(Location, T) 13 { 14 alias LocationDiff = typeof(Location.init - Location.init); 15 16 /** 17 Start location. 18 */ 19 Location start; 20 21 /** 22 Value for nonterminal or token. 23 */ 24 T val; 25 26 /** 27 Constructor. 28 */ 29 this(Location start, T val) 30 { 31 this.start = start; 32 this.val = val; 33 } 34 35 /** 36 Length of the value. 37 */ 38 LocationDiff inputLength()() const 39 { 40 static if (is(typeof(val.inputLength))) 41 { 42 static if (__traits(compiles, tree is null)) 43 if (val is null) 44 return LocationDiff(); 45 return val.inputLength; 46 } 47 else static if (is(T == string)) 48 { 49 return LocationDiff.fromStr(val); 50 } 51 else static if (is(T == X[], X)) 52 { 53 assert(false); 54 } 55 else static if (is(T == typeof(null))) 56 return LocationDiff(); 57 else 58 static assert(0, T.stringof); 59 } 60 61 /** 62 End location for the location. 63 */ 64 Location end()() const 65 { 66 static if (is(typeof(val.end))) 67 { 68 static if (__traits(compiles, tree is null)) 69 if (val is null) 70 return Location.invalid; 71 return val.end; 72 } 73 else 74 return start + inputLength; 75 } 76 }