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)*) }