xdr-codegen 0.5.2

XDR code generation
STRUCT = {"struct"}
UNION = {"union"}
NAMESPACE = {"namespace"}
CASE = {"case"}
SWITCH = {"switch"}
TYPEDEF = {"typedef"}
TYPE = {"type"}
ENUM = {"enum"}
VOID = {"void"}

keywords = {
    STRUCT |
    UNION |
    NAMESPACE |
    CASE |
    SWITCH |
    TYPEDEF |
    ENUM |
    VOID |
    TYPE
}


types = {
    "boolean" |
    "string" |
    "opaque" |
    "int" |
    "unsigned int" |
    "hyper" |
    "unsigned hyper" |
    "float" |
    "double" |
    "quad"
}

ws_no_nl = _{ " " | "\t" }
whitespace = _{ ws_no_nl | NEWLINE }
lowercase = {'a' .. 'z'}
uppercase = {'A' .. 'Z'}
alpha = { lowercase | uppercase }
num = { '0'..'9' }
alpha_num = { alpha | num }
id_char = { alpha_num | "_" }


line_comment = _{ ("//" | "%") ~ (!NEWLINE ~ ANY)* }

long_comment = _{ "/*" ~ (!"*/" ~ ANY)* ~ "*/"}
empty_space = _{whitespace | line_comment | long_comment }

num_p = { num+ }
var_array = { "<" ~ num* ~ ">" }
fixed_array = { "[" ~ num_p ~ "]" }
array_def = { var_array | fixed_array }
identifier = { !keywords ~ alpha ~ (alpha_num | "_")* }
bracket_start = { ws_no_nl+ ~ identifier ~ whitespace* ~ "{" }
end_bracket = {"}" ~ ";"?}
single_param = { "(" ~ ws_no_nl* ~ identifier ~ ws_no_nl+ ~ identifier ~ ")" }
tag = {  "[" ~ ws_no_nl* ~ identifier ~ ws_no_nl* ~ "]" }

type_decl = { tag? ~ empty_space* ~ ( types | identifier ) ~ ws_no_nl+ ~ identifier ~ array_def? ~";" }
typedef = { TYPEDEF ~ whitespace+ ~ type_decl }
enum_decl = { identifier ~ ws_no_nl+ ~ "=" ~ ws_no_nl ~ num_p ~ ws_no_nl* ~ ","? }
case_statement = { CASE ~ ws_no_nl+ ~ identifier ~ ":" ~ NEWLINE ~ empty_space+ ~ (type_decl | VOID ~ ";") }

switch = {SWITCH ~ ws_no_nl* ~ single_param ~ whitespace* ~ "{" ~ (empty_space | case_statement)* ~ end_bracket}
union = { UNION ~ ws_no_nl+ ~ identifier ~ ws_no_nl+ ~ switch }
Struct = {tag? ~ empty_space* ~ STRUCT ~ bracket_start ~ (empty_space | type_decl)* ~ end_bracket }
Enum = {ENUM ~ bracket_start ~ (empty_space | enum_decl)* ~ end_bracket }
namespace = { NAMESPACE ~ bracket_start ~ (empty_space | Struct | typedef | Enum | union)* ~ end_bracket}


file = { SOI ~ (empty_space* ~ namespace ~ empty_space*)+ ~ EOI}