This is a grammar in ANTLR for a config markup language, similar to OGRE Scripts:
// This is a comment
object_keyword "Example/ObjectName"
{
attribute_name "some value"
list_of_strings_attribute [
"item #1" "item #2"
"item #3" "item #4" "item #5"
]
object_keyword2 "Nested Object"
{
other_attribute 1 2 3
/* block comment */
}
}
This repo includes a parser implementation in C++, so grammar is spiced up with the C++-specific actions.
First, generate the C++ sources for the grammar parser using ANTLR 4.13.0 JAR:
java -jar antlr-4.13.0-complete.jar -o gen_parser -Dlanguage=Cpp ConfigScript.g4
NOTE: it is important to keep ANTLR4 generator version in sync with what is provided by the vcpkg.
Run CMake specifying vcpkg as a toolchain:
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE="[path to vcpkg]/scripts/buildsystems/vcpkg.cmake"
Then, build the project:
cmake --build build
First, add the necessary headers to your code:
#include "parser.hpp"
Parse the code:
const auto configSource = R"(
// This is a comment
my_object_1 "Example/ObjectName" // <--- this can not be just Example/ObjectName (no quotes)
{
some_attribute "some value"
list_of_strings_attribute [
"item #1" "item #2"
"item #3" "item #4" "item #5"
]
my_object_2 "Nested Object"
{
other_attribute 1 2 3
// and so on..
/* block comment */
}
}
)";
// parse the source
auto config = ConfigScript::Parser::parse(configSource);
The config
variable would then contain a list (std::vector
) of top-level objects from the config.
To access the top-level object properties, use
std::map<std::string, ConfigScript::PropertyType> properties = config[0].properties;
ConfigScripr::PropertyType
is an alias for std::variant
containing all possible value types:
int
andfloat
vectors of 2, 3 or 4 components:Vec2i
,Vec3i
,Vec4i
,Vec2f
,Vec3f
,Vec4f
std::string
bool
int
float
- lists of strings (
std::vector<std::string>
) - objects, represented as
ConfigScript::Object { std::string name; std::string classifier; std::map<std::string, ConfigScript::PropertyType> properties; }
Since PropertyType
is alias for std::variant
, you would have to cast it to whatever it is underneath in order to access a specific property value:
auto property1 = std::get<std::string>(propertyValue1); // string values
auto property2 = std::get<ConfigScript::Vec3f>(propertyValue2); // 4-component float vector
Objects can have a classifier, which is a string following the object name:
object_name "object classifier"
{
// properties
}