/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: Parser.hpp Date: 2021-6-9 Author: Reece ***/ #pragma once #include namespace Aurora::Parse { enum class ParsableTag { kParseUInt = (const int)Aurora::Data::DataType::kTypeUInt, kParseSInt = (const int)Aurora::Data::DataType::kTypeSInt, kParseNumber = (const int)Aurora::Data::DataType::kTypeNumber, kParseString = (const int)Aurora::Data::DataType::kTypeString, kParseBoolean = (const int)Aurora::Data::DataType::kTypeBoolean, kParseUUID = (const int)Aurora::Data::DataType::kTypeUUID, kParseVec3 = (const int)Aurora::Data::DataType::kTypeVec3, kParseVec4 = (const int)Aurora::Data::DataType::kTypeVec4, kParseObject, kParseStringVararg }; struct ParseBit; struct ParsedBit; using ParseObject = AuList; using ParsedObject = AuList; using ParsePrimativeValue = Aurora::Data::PrimitiveValue; using ParseValue = Aurora::Data::Value; struct ParseValueEx : ParseValue { ParsedObject Object; }; struct ParseBit { ParseBit(ParsableTag _Tag, const AuString &_Label) : tag(_Tag), label(_Label) { } ParseBit(ParsableTag _Tag, const AuString &_Label, bool _Array, bool _Optional, bool _vararg) : tag(_Tag), label(_Label), array(_Array), optional(_Optional), vararg(_vararg) { } ParseBit(ParsableTag _Tag) : tag(_Tag) { } ParseBit(ParsableTag _Tag, bool _Array, bool _Optional, bool _vararg) : tag(_Tag), array(_Array), optional(_Optional), vararg(_vararg) { } ParseBit(ParseObject _ObjectParse) : tag(ParsableTag::kParseObject), objectParse(_ObjectParse) { } ParseBit(ParseObject _ObjectParse, const AuString &_Label) : tag(ParsableTag::kParseObject), objectParse(_ObjectParse), label(_Label) { } // marks this "parse bit" and all following part bits optional bool optional = false; // if true, the lexer yoinks a length prefix token before iterating over array length bool array = false; // if true, the lexer parses tag or object parse until EOS bool vararg = false; // parse defintion ParsableTag tag; ParseObject objectParse; // optional: AuString label = ""; // parse object // {...} // single parse bit: // // optional: // () // var arg: // ( ...) // arrays // [ ] }; struct ParsedBit { ParsedBit() { } ParsedBit(ParsableTag _tag) : tag(_tag) { } AuMach count; ParsableTag tag; bool isArray; struct { ParseValueEx single; AuList array; } value; }; struct ParseResult { AuString SyntaxError; AuString DebugTree; ParsedObject result; }; using ConsumeStream_cb = std::function; static ConsumeStream_cb StringToConsumable(const AuString &str, AuMach &index) { auto getc = [&](AuUInt8 &byt) mutable { if (index == str.length()) { return false; } byt = str[index]; index++; return true; }; return getc; } AUKN_SYM void VaildateStructure(const ParseObject &object); AUKN_SYM bool ConsumeToken(ParsableTag type, ConsumeStream_cb getc, ParseValue &out); static bool ConsumeToken(ParsableTag type, const AuString &str, AuMach &index, ParseValueEx &out) { return ConsumeToken(type, StringToConsumable(str, index), out); } static bool ConsumeToken(ParsableTag type, const AuString &str, ParseValueEx &out) { AuMach index{}; return ConsumeToken(type, StringToConsumable(str, index), out); } AUKN_SYM bool Parse(ParseResult &result, const ParseObject &structure, ConsumeStream_cb getc); static bool Parse(ParseResult &result, const ParseObject &structure, const AuString &str, AuMach &index) { return Parse(result, structure, StringToConsumable(str, index)); } static bool Parse(ParseResult &result, const ParseObject &structure, const AuString &str) { AuMach index{}; return Parse(result, structure, StringToConsumable(str, index)); } AUKN_SYM void SerializeToken(ParsableTag type, const ParseValue &value, AuString &str); AUKN_SYM void Serialize(const ParsedObject &structure, AuString &ret); }