ice-rs 0.3.0

ZeroC Ice for Rust
Documentation
ice = { 
    SOI ~ NEWLINE* ~ 
    pragma? ~ NEWLINE* ~ 
    (lang_include | file_include)* ~ NEWLINE* ~ 
    (module_block)+ ~ 
    EOI 
}

WHITESPACE = _{ " " | "\t" }
COMMENT = _{ ("//" ~ (!NEWLINE ~ ANY)*) | ( "/*" ~ ("!*/" ~ ANY)*) }

pragma = _{ "#pragma once" }
lang_include = _{ "[["  ~ (!"]]" ~ ANY)* ~ "]]"}
lang_define = _{ "["  ~ (!"]" ~ ANY)* ~ "]" ~ NEWLINE?}

identifier = @{ ASCII_ALPHA ~ (ASCII_DIGIT | ASCII_ALPHA | "_")* }
value = { (!NEWLINE ~ ANY)* }
typename = { identifier ~ ("<" ~ identifier ~ ("," ~ identifier)* ~ ">")? }
numeric_value = { (!NEWLINE ~ !ASCII_ALPHA ~ ASCII_DIGIT)+ }

keyword_out = { "out" }
keyword_module = { "module" }
keyword_interface = { "interface" }
keyword_enum = { "enum" }
keyword_struct = { "struct" }
keyword_class = { "class" }
keyword_throws = { "throws" }
keyword_exception = { "exception" }
keyword_extends = { "extends" }
keyword_optional = { "optional" ~ "(" ~ optional_tag ~ ")" }
keyword_include = { "#include" }
keyword_idempotent = { "idempotent" }

optional_tag = { ASCII_DIGIT+ }
file_include = { keyword_include ~ "<" ~ identifier ~ ".ice" ~ ">" ~ NEWLINE* }
block_open = { NEWLINE* ~ "{" ~ NEWLINE* }
block_close = { "}" ~ ";"? ~ NEWLINE* }

any_block = { module_block | interface_block | enum_block | struct_block| class_block | exception_block }

module_block = { keyword_module ~ identifier ~ block_open ~ (any_block | typedef | lang_define)* ~ block_close }
interface_block = { keyword_interface ~ identifier ~ block_open ~ (function)* ~ block_close }
enum_block = { keyword_enum ~ identifier ~ block_open ~ enum_lines ~ block_close }
struct_block = { keyword_struct ~ identifier ~ block_open ~ struct_line+ ~ block_close }
extends = { keyword_extends ~ identifier }
class_block = { keyword_class ~ identifier ~ extends? ~ block_open ~ class_line+ ~ block_close }
exception_block = { keyword_exception ~ identifier ~ extends? ~ block_open ~ struct_line* ~ block_close }

fn_return = { keyword_optional? ~ identifier }
fn_return_proxy = { "*" }
fn_name = { identifier }
fn_arg_open = { "(" }
fn_arg = { !keyword_out ~ keyword_optional? ~ typename ~ identifier }
fn_arg_out = { keyword_out ~ keyword_optional? ~ typename ~ identifier }
fn_arg_list = {
    (fn_arg ~ ("," ~ NEWLINE? ~ fn_arg)*)? ~ NEWLINE? ~ (fn_arg_out? ~ ("," ~ fn_arg_out)*)?
}
fn_arg_close = { ")" }
fn_throws = { keyword_throws ~ identifier }
function = {
    keyword_idempotent? ~
    fn_return ~
    fn_return_proxy? ~
    fn_name ~
    fn_arg_open ~ NEWLINE? ~
    fn_arg_list ~
    fn_arg_close ~ NEWLINE? ~
    fn_throws? ~
    ";" ~
    NEWLINE*
}

enum_line = { identifier ~ ("=" ~ numeric_value)? }
enum_lines = { (enum_line ~ ","? ~ NEWLINE?)* }

struct_line_end = { ";" }
struct_line_default = { "=" ~ value }
struct_line = { typename ~ identifier ~ (struct_line_default | struct_line_end) ~ NEWLINE* }

class_line_end = { ";" }
class_line_default = { "=" ~ value }
class_line = { keyword_optional? ~ typename ~ identifier ~ (class_line_default | class_line_end) ~ NEWLINE* }


typedef_end = { ";" }
typedef = { typename ~ identifier ~ typedef_end ~ NEWLINE* }