163 lines
4.9 KiB
C++
163 lines
4.9 KiB
C++
|
/***
|
||
|
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 <Aurora/Data/Data.hpp>
|
||
|
|
||
|
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<ParseBit>;
|
||
|
using ParsedObject = AuList<ParsedBit>;
|
||
|
|
||
|
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:
|
||
|
// <tag-label: value>
|
||
|
// optional:
|
||
|
// <max-number: value> <min-number: value> (<min-number: value>)
|
||
|
// var arg:
|
||
|
// <max-number: value> <min-number: value> (<min-number: value> ...)
|
||
|
// arrays
|
||
|
// <max-number: value> <min-number: value> [<array count> <min-number: value>]
|
||
|
};
|
||
|
|
||
|
struct ParsedBit
|
||
|
{
|
||
|
ParsedBit()
|
||
|
{
|
||
|
}
|
||
|
ParsedBit(ParsableTag _tag) : tag(_tag)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
AuMach count;
|
||
|
ParsableTag tag;
|
||
|
bool isArray;
|
||
|
|
||
|
struct
|
||
|
{
|
||
|
ParseValueEx single;
|
||
|
AuList<ParseValueEx> array;
|
||
|
} value;
|
||
|
};
|
||
|
|
||
|
struct ParseResult
|
||
|
{
|
||
|
AuString SyntaxError;
|
||
|
AuString DebugTree;
|
||
|
ParsedObject result;
|
||
|
};
|
||
|
|
||
|
using ConsumeStream_cb = std::function<bool(AuUInt8 &)>;
|
||
|
|
||
|
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);
|
||
|
}
|