AuroraRuntime/Include/Aurora/Parse/Parser.hpp
2021-06-27 22:25:29 +01:00

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);
}