yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
b118451e3
master
1// slang-json-parser.h 2#ifndef SLANG_JSON_PARSER_H 3#define SLANG_JSON_PARSER_H 4 5#include "slang-json-lexer.h" 6 7 8namespace Slang 9{ 10 11class JSONListener 12{ 13public : 14/// Start an object 15virtual void startObject (SourceLoc loc )= 0 ; 16/// End an object 17virtual void endObject (SourceLoc loc )= 0 ; 18/// Start an array 19virtual void startArray (SourceLoc loc )= 0 ; 20/// End and array 21virtual void endArray (SourceLoc loc )= 0 ; 22 23 24/// Add the key. Must be followed by addXXXValue. 25virtual void addQuotedKey (const UnownedStringSlice & key ,SourceLoc loc )= 0 ; 26virtual void addUnquotedKey (const UnownedStringSlice & key ,SourceLoc loc )= 0 ; 27/// Can be performed in an array or after an addLexemeKey in an object 28virtual void addLexemeValue ( 29JSONTokenType type , 30const UnownedStringSlice & value , 31SourceLoc loc )= 0 ; 32 33/// An integer value 34virtual void addIntegerValue (int64_t value ,SourceLoc loc )= 0 ; 35/// Add a floating point value 36virtual void addFloatValue (double value ,SourceLoc loc )= 0 ; 37/// Add a boolean value 38virtual void addBoolValue (bool value ,SourceLoc loc )= 0 ; 39 40/// Add a string value. NOTE! string is unescaped/quoted 41virtual void addStringValue (const UnownedStringSlice & string ,SourceLoc loc )= 0 ; 42 43/// Add a null value 44virtual void addNullValue (SourceLoc loc )= 0 ; 45}; 46 47class JSONWriter :public JSONListener 48{ 49public : 50/* 51https://en.wikipedia.org/wiki/Indentation_style 52*/ 53enum class IndentationStyle 54 { 55Allman ,///< After every value, and opening, closing all other types 56KNR ,///< K&R like. Fields have CR. 57 }; 58 59enum class LocationType :uint8_t 60 { 61Object , 62Array , 63Comma , 64 }; 65 66// NOTE! Order must be kept the same without fixing is functions below 67enum class Location 68 { 69BeforeOpenObject , 70BeforeCloseObject , 71AfterOpenObject , 72AfterCloseObject , 73 74BeforeOpenArray , 75BeforeCloseArray , 76AfterOpenArray , 77AfterCloseArray , 78 79FieldComma , 80Comma , 81 82CountOf , 83 }; 84 85static LocationType getLocationType (Location loc ) 86 { 87return isObject (loc ) ?LocationType ::Object 88 : (isComma (loc ) ?LocationType ::Comma :LocationType ::Array ); 89 } 90 91static bool isObjectLike (Location loc ) 92 { 93return Index (loc ) <=Index (Location ::AfterCloseArray ); 94 } 95static bool isObject (Location loc ) {return Index (loc ) <=Index (Location ::AfterCloseObject ); } 96static bool isArray (Location loc ) 97 { 98return Index (loc ) >=Index (Location ::BeforeOpenArray )&& 99Index (loc ) <=Index (Location ::AfterCloseArray ); 100 } 101static bool isComma (Location loc ) {return Index (loc ) >=Index (Location ::FieldComma ); } 102static bool isOpen (Location loc ) {return isObjectLike (loc )&& (Index (loc )& 1 )== 0 ; } 103static bool isClose (Location loc ) {return isObjectLike (loc )&& (Index (loc )& 1 )!= 0 ; } 104static bool isBefore (Location loc ) {return isObjectLike (loc )&& (Index (loc )& 2 )== 0 ; } 105static bool isAfter (Location loc ) {return isObjectLike (loc )&& (Index (loc )& 2 )!= 0 ; } 106 107// Implement JSONListener 108virtual void startObject (SourceLoc loc )SLANG_OVERRIDE ; 109virtual void endObject (SourceLoc loc )SLANG_OVERRIDE ; 110virtual void startArray (SourceLoc loc )SLANG_OVERRIDE ; 111virtual void endArray (SourceLoc loc )SLANG_OVERRIDE ; 112virtual void addQuotedKey (const UnownedStringSlice & key ,SourceLoc loc )SLANG_OVERRIDE ; 113virtual void addUnquotedKey (const UnownedStringSlice & key ,SourceLoc loc )SLANG_OVERRIDE ; 114virtual void addLexemeValue (JSONTokenType type ,const UnownedStringSlice & value ,SourceLoc loc ) 115SLANG_OVERRIDE ; 116virtual void addIntegerValue (int64_t value ,SourceLoc loc )SLANG_OVERRIDE ; 117virtual void addFloatValue (double value ,SourceLoc loc )SLANG_OVERRIDE ; 118virtual void addBoolValue (bool value ,SourceLoc loc )SLANG_OVERRIDE ; 119virtual void addStringValue (const UnownedStringSlice & string ,SourceLoc loc )SLANG_OVERRIDE ; 120virtual void addNullValue (SourceLoc loc )SLANG_OVERRIDE ; 121 122/// Get the builder 123StringBuilder & getBuilder () {return m_builder ; } 124 125JSONWriter (IndentationStyle format ,Index lineLengthLimit = -1 ) 126 { 127m_format = format ; 128m_lineLengthLimit = lineLengthLimit ; 129 130m_state .m_kind = State ::Kind ::Root ; 131m_state .m_flags = 0 ; 132 } 133 134protected : 135struct State 136 { 137enum class Kind :uint8_t 138 { 139Root , 140Object , 141Array , 142 }; 143 144typedef uint8_t Flags ; 145struct Flag 146 { 147enum Enum :Flags 148 { 149HasPrevious = 0x01 , 150HasKey = 0x02 , 151 }; 152 }; 153 154bool canEmitValue ()const 155 { 156switch (m_kind ) 157 { 158case Kind ::Root : 159return (m_flags & Flag ::HasPrevious )== 0 ; 160case Kind ::Array : 161return true ; 162case Kind ::Object : 163return (m_flags & Flag ::HasKey )!= 0 ; 164default : 165return false ; 166} 167} 168 169Kind m_kind ; 170Flags m_flags ; 171}; 172 173void _maybeNextLine (); 174void _nextLine (); 175void _handleFormat ( Location loc ); 176 177Index _getLineLengthAfterIndent (); 178 179/// Only emits the indent if at start of line 180void _maybeEmitIndent (); 181void _emitIndent (); 182 183void _maybeEmitComma (); 184void _maybeEmitFieldComma (); 185 186void _preValue ( SourceLoc loc ); 187void _postValue (); 188 189void _indent () { m_currentIndent ++ ; } 190void _dedent () 191{ 192-- m_currentIndent ; 193SLANG_ASSERT ( m_currentIndent >= 0 ); 194} 195 196/// True if the line is indented at the required level 197bool _hasIndent () { return m_emittedIndent >= 0 && m_emittedIndent == m_currentIndent ; } 198 199Index m_currentIndent = 0 ; 200char m_indentChar = ' ' ; 201Index m_indentCharCount = 4 ; 202 203Index m_lineIndex = 0 ; 204Index m_lineStart = 0 ; 205Index m_emittedIndent = -1 ; /// If -1 for current line there is no indent emitted 206 207Index m_lineLengthLimit = -1 ; /// The limit is only applied *AFTER* indentation 208 209IndentationStyle m_format ; 210 211StringBuilder m_builder ; 212List < State > m_stack ; 213State m_state ; 214}; 215 216class JSONParser 217{ 218public : 219SlangResult parse ( 220JSONLexer * lexer , 221SourceView * sourceView , 222JSONListener * listener , 223DiagnosticSink * sink ); 224 225protected : 226SlangResult _parseValue (); 227SlangResult _parseObject (); 228SlangResult _parseArray (); 229 230SourceView * m_sourceView ; 231DiagnosticSink * m_sink ; 232JSONListener * m_listener ; 233JSONLexer * m_lexer ; 234}; 235 236 237} // namespace Slang 238 239#endif