#ifndef ARC_STD_PARSER_PARSERLANG_H_
#define ARC_STD_PARSER_PARSERLANG_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "arc/std/parser.h"

/*
<line>          -> <body> NEWLINE <line> | <body> | NEWLINE <line> | LAMBDA
<body>          -> <tag> <whitespace> ARROW <whitespace> <arguments>

<arguments>     -> <argument> <whitespace> OR <whitespace> <arguments> | <argument>
<argument>      -> <tagOrConstant> <whitespace> <argument> | <tagOrConstant>
<tagOrConstant> -> <tag> | <constant>

<constant>      -> ALPHA_UPPER_CHAR <constantBody>
<constantBody>  -> <constantChar> <constantBody> | LAMBDA
<constantChar>  -> ALPHA_UPPER_CHAR | UNDERSCORE

<tag>           -> LESS_THAN <variable> GREATER_THAN
<variable>      -> <alphaChar> <variableBody> | UNDERSCORE <variableBody>
<variableBody>  -> <variableChar> <variableBody> | LAMBDA
<variableChar>  -> <alphaChar> | NUMBER | UNDERSCORE
<alphaChar>     -> ALPHA_LOWER_CHAR | ALPHA_UPPER_CHAR

<whitespace>    -> WHITESPACE <whitespace> | WHITESPACE
*/

/**
 * @brief creates a parser for the Parser Lang
 *
 * @note the rules will be inited for the parser lang
 * @note the parsed data will be saved as a vector of ARC_ParserLanguageTag
 *
 * @param[out] parser the parser to create
*/
void ARC_ParserLang_CreateAsParser(ARC_Parser **parser, ARC_Parser_GetStringIdFn getStringIdFn);

#define ARC_PARSERLANG_TOKEN_NULL             0
#define ARC_PARSERLANG_TOKEN_NUMBER           1
#define ARC_PARSERLANG_TOKEN_ALPHA_LOWER_CHAR 2
#define ARC_PARSERLANG_TOKEN_ALPHA_UPPER_CHAR 3
#define ARC_PARSERLANG_TOKEN_WHITESPACE       4

#define ARC_PARSERLANG_TOKEN_NEWLINE_ID        5
#define ARC_PARSERLANG_TOKEN_NEWLINE_CHAR      '\n'
#define ARC_PARSERLANG_TOKEN_LESS_THAN_ID      6
#define ARC_PARSERLANG_TOKEN_LESS_THAN_CHAR    '<'
#define ARC_PARSERLANG_TOKEN_GREATER_THAN_ID   7
#define ARC_PARSERLANG_TOKEN_GREATER_THAN_CHAR '>'
#define ARC_PARSERLANG_TOKEN_OR_ID             8
#define ARC_PARSERLANG_TOKEN_OR_CHAR           '|'
#define ARC_PARSERLANG_TOKEN_UNDERSCORE_ID     9
#define ARC_PARSERLANG_TOKEN_UNDERSCORE_CHAR   '_'

#define ARC_PARSERLANG_TOKEN_ARROW_ID      10
#define ARC_PARSERLANG_TOKEN_ARROW_CSTRING "->"

#define ARC_PARSERLANG_LAMBDA          ARC_PARSER_TAG_LAMBDA
#define ARC_PARSERLANG_LINE            11
#define ARC_PARSERLANG_BODY            12
#define ARC_PARSERLANG_ARGUMENTS       13
#define ARC_PARSERLANG_ARGUMENT        14
#define ARC_PARSERLANG_TAG_OR_CONSTANT 15
#define ARC_PARSERLANG_CONSTANT        16
#define ARC_PARSERLANG_CONSTANT_BODY   17
#define ARC_PARSERLANG_CONSTANT_CHAR   18
#define ARC_PARSERLANG_TAG             19
#define ARC_PARSERLANG_VARIABLE        20
#define ARC_PARSERLANG_VARIABLE_BODY   21
#define ARC_PARSERLANG_VARIABLE_CHAR   22
#define ARC_PARSERLANG_ALPHA_CHAR      23
#define ARC_PARSERLANG_WHITESPACE      24

#ifdef __cplusplus
}
#endif

#endif //ARC_STD_PARSER_PARSERLANG_H_
