fkl-parser 0.4.0

Feakin is a architecture design and visual collaboration tool. This is the parser for Feakin.
Documentation
declarations = _{ SOI ~ declaration* ~ EOI }

declaration = {
  include_decl
  | context_map_decl
  | context_decl
  | ext_module_decl
  | aggregate_decl
  | entity_decl
  | value_object_decl
  | struct_decl
  // ddd
  | component_decl
  | implementation_decl
  | layered_decl
  // extension
  | source_sets_decl
  // env
  | env_decl
}

include_decl = { "include" ~ string }

context_map_decl = {
  "ContextMap" ~ identifier? ~ "{" ~ (context_decl | used_context_node | context_node_rel | inline_doc)* ~ "}"
}

context_decl = {
  "Context" ~ identifier ~ "{" ~ (aggregate_decl | used_domain_objects_decl | inline_doc)* ~ "}"
}

used_context_node = {
  ("Context" | "context") ~ identifier ~ ("," ~ identifier)*
}

used_domain_event_decl = {
  "DomainEvent" ~ event_name ~ ("," ~ event_name)* ~ ";"?
}

// domain_event_binding = {
//   identifier ~ ("(" ~ "impl" ~ "=" ~ binding_id ~ ")")?
// }

event_name = {
  identifier *
}

context_node_rel = {
  left_id ~ left_rel_defs? ~ rel_symbol ~ ((right_id ~ right_rel_defs?) | (right_rel_defs? ~ right_id)) ~ ";"?
}

left_id = { identifier }
right_id = { identifier }

left_rel_defs = { rel_defs }
right_rel_defs = { rel_defs }

rel_defs = {
  "[" ~ "rel" ~ "=" ~ identifier ~ "]"
  | "[" ~ "rel" ~ "=" ~ "\"" ~ (identifier ~ ","?)* ~ "\"" ~ "]"
  | "[" ~ identifier ~ "]"
}

rel_keyword = {
  "rel" | "relation"
}

rel_symbol = {
  rs_both | rs_left_to_right | rs_right_to_left
}

rs_left_to_right = { "->" }
rs_right_to_left = { "<-" }
rs_both = { "<->" }

module_decl = {
  "Module" ~ identifier ~ "{" ~ (aggregate_decl | inline_doc)* ~ "}"
}

ext_module_decl = {
  module_decl
}

aggregate_decl = {
  "Aggregate" ~ identifier ~ "{" ~ (entity_decl | struct_decl | inline_doc | used_domain_event_decl | used_domain_objects_decl )* ~ "}"
}

used_domain_objects_decl = {
  ("Concept" | "Entity" | "VO" | "ValueObject" | "Aggregate" ) ~ identifier ~ ("," ~ identifier)* ~ ";"
}

entity_decl = {
  ("Concept" | "Entity" ) ~ identifier ~ "{" ~ (constructor_decl | struct_decl | value_object_decl | inline_doc)* ~ "}"
}

value_object_decl = {
  ("VO" | "ValueObject") ~ identifier ~ ("{" ~ (constructor_decl | struct_decl)* ~ "}")?
}

constructor_decl = {
  "constructor" ~ "(" ~ parameters_decl ~ ")"
}

struct_decl = {
  ("struct" | "Struct") ~ identifier? ~ "{" ~ fields_decl ~ "}"
}

implementation_decl = {
  "impl" ~ identifier ~ "{" ~ (inline_doc | endpoint_decl | flow_decl | set_target_object )* ~ "}"
}

endpoint_decl = {
  "endpoint" ~ "{" ~ http_request_decl ~ request_body? ~ authorization_decl? ~ http_response_decl? ~ "}"
}

set_target_object = {
  "aggregate" ~ ":" ~ set_aggregate_name ~ ";"?
  | "entity" ~ ":" ~ set_entity_name ~ ";"?
}

set_aggregate_name = { identifier }
set_entity_name = { identifier }

flow_decl = {
  "flow" ~ "{" ~ (via_method_decl | via_message_decl)* ~ "}"
}

via_method_decl = {
  "via" ~ object_name ~ (("::" | ".") ~ method_name ~ ("(" ~ parameters_decl? ~ ")")?)? ~ "receive" ~ receive_object ~ ";"?
}

via_message_decl = {
  "via" ~ object_name ~ "send" ~ pass_object ~ "to" ~ topic_name ~ ";"?
}

layered_decl = {
  "layered" ~ identifier ~ "{" ~ (inline_doc | dependency_decl | layer_decl)* ~ "}"
}

layer_decl = {
  "layer" ~ identifier ~ "{" ~ (inline_doc | (package_def)*)? ~ "}"
}

package_def = {
  "package" ~ ":" ~ package ~ ";"?
}

dependency_decl = {
  "dependency" ~ "{" ~ dependency_entry* ~ "}"
}

dependency_entry = {
  source ~ rs_left_to_right  ~ target
}

source = { identifier | string }
target = { identifier | string }
package = { string }

object_name = {  identifier }
method_name = {  identifier }
receive_object = {  name_type_def }
pass_object = {  identifier }
topic_name = {  string }

http_response_decl = {
  "response" ~ ":" ~ identifier ~ ";"?
}

authorization_decl = {
  "authorization" ~ ":" ~ (string | authorization_type ~ username? ~ password? )~ ";"?
}

authorization_type = { identifier }

username =  { special_string }
password =  { special_string }

http_request_decl = {
  http_method ~ uri ~ ";"?
}

http_method = {
  "GET" | "POST" | "PUT" | "DELETE" | "PATCH"
}

uri = { string }

url_origin = {
  scheme  ~ "://" ~ host ~ (":" ~ port)?
}

scheme = { special_string }
host = {
  special_string ~ ("." ~ special_string)*
}

port = { number }
path = { uri_string }
query = { "?" ~ special_string ~ ("&" ~ special_string)* }
frag = { "#" ~ special_string }

request_body = {
  "request"  ~ ":" ~ (identifier | struct_decl) ~ ";"?
}

parameters_decl = {
  (name_type_def ~ ","?)*
}

fields_decl = {
  (name_type_def ~ ";"?)*
}

// list?
name_type_def = {
  identifier ~ ":" ~ param_type ~ ("=" ~ value)?
}

value = {
  identifier ~ "." ~ identifier // enum
  | identifier
  | number
  | string
}

param_type = {
  list ~ "<" ~ identifier ~ ">"
  | identifier
}

component_decl = {
  "Component" ~ identifier ~ "{" ~ (attr_decl | inline_doc | used_domain_objects_decl )* ~ "}"
}

source_sets_decl = {
  "SourceSet" ~ identifier ~ "{" ~ (source_set_decl | inline_doc)* ~ "}"
}

source_set_decl = {
  identifier ~ "{" ~ (attr_decl | inline_doc)* ~ "}"
}

env_decl = {
  "env" ~ identifier ~ "{" ~ inline_doc? ~ (datasource_decl | server_decl | custom_decl )* ~ "}"
}

datasource_decl = {
  "datasource" ~ "{" ~ (attr_decl | inline_doc)* ~ "}"
}

server_decl = {
  "server" ~ "{" ~ (attr_decl | inline_doc)* ~ "}"
}

custom_decl = {
  identifier ~ "{" ~ (attr_decl | inline_doc)* ~ "}"
}

// ----------------------------- Attr -----------------------------

attr_decl = {
  identifier ~ (":" | "=") ~ (attr_value | attr_list) ~ ";"?
}

attr_list = {
 "[" ~ (attr_value ~ ","?)* ~ "]"
}

attr_value = {
  identifier | string
}

list = {
 "List" | "Vec" | "Set" | identifier
}


// ----------------------------- Lexer -----------------------------

keywords = _{
  // DDD Keywords
  "ContextMap" | "Context"
  //  Domain Analysis Keywords
  | "SubDomain" | "GenericDomain" | "SupportingDomain" | "CoreDomain"
  // Strategic
  // TODO?
  // Tactic Keywords
  | "Aggregate" | "Entity" | "ValueObject" | "VO" | "Service" | "DomainEvent" | "CommandEvent"
  // Implementation - Layered Keywords
  | "Module" | "Repository" | "Service" | "Factory" | "ApplicationService" | "DomainService"
  // Implementation - APIs
  | "ApiEndpoints"
  // TODO: DDD Relationship
  | bounded_context_relation
}

// align to BoundedContextRelation
bounded_context_relation = {
  "SharedKernel" | "Partnership" | "CustomerSupplier" | "Conformist" | "AntiCorruptionLayer" | "OpenHostService" | "PublishedLanguage"
}

double_quoted_string  = @{ "\"" ~ (!("\"") ~ ANY)* ~ "\""}
single_quoted_string  = @{ "\'" ~ (!("\'") ~ ANY)* ~ "\'"}

identifier = @{
 !keywords ~ (ASCII_ALPHA | ASCII_ALPHANUMERIC | "_") ~ (ASCII_ALPHANUMERIC | "_")*
}

// normal
string = @{
    double_quoted_string |
    single_quoted_string
}
number = @{ '0'..'9'+ }
int = @{ number | "-" ~ "0"* ~ '1'..'9' ~ number? }
special_string = @{ (ASCII_ALPHANUMERIC | "-" | "_" )* }
uri_string = @{ (ASCII_ALPHANUMERIC | "-" | "_" | "{" | "}" )* }

inline_doc = {
  "\"\"\"" ~ (!"\"\"\"" ~ ANY)* ~ "\"\"\""
}

// comments
newline    = _{ "\n" | "\r\n" }
WHITESPACE = _{ " " | "\t" | newline }
block_comment = _{ "/*" ~ (block_comment | !"*/" ~ ANY)* ~ "*/" }
COMMENT    = _{ block_comment | ("//" ~ (!newline ~ ANY)*) }