// SysMLv2 Grammar - Minimal Starting Point
// This will be incrementally expanded following TDD
WHITESPACE = _{ " " | "\t" | "\r" | "\n" }
COMMENT = _{ line_comment }
line_comment = { "//" ~ (!"\n" ~ ANY)* }
block_comment = { "/*" ~ (!"*/" ~ ANY)* ~ "*/" }
// Tokens
verification_token = @{ "verification" ~ !(ASCII_ALPHANUMERIC | "_") }
stakeholder_token = @{ "stakeholder" ~ !(ASCII_ALPHANUMERIC | "_") }
requirement_token = @{ "requirement" ~ !(ASCII_ALPHANUMERIC | "_") }
redefines_token = @{ "redefines" ~ !(ASCII_ALPHANUMERIC | "_") }
references_token = @{ "references" ~ !(ASCII_ALPHANUMERIC | "_") }
individual_token = @{ "individual" ~ !(ASCII_ALPHANUMERIC | "_") }
constraint_token = @{ "constraint" ~ !(ASCII_ALPHANUMERIC | "_") }
connection_token = @{ "connection" ~ !(ASCII_ALPHANUMERIC | "_") }
allocation_token = @{ "allocation" ~ !(ASCII_ALPHANUMERIC | "_") }
dependency_token = @{ "dependency" ~ !(ASCII_ALPHANUMERIC | "_") }
occurrence_token = @{ "occurrence" ~ !(ASCII_ALPHANUMERIC | "_") }
rendering_token = @{ "rendering" ~ !(ASCII_ALPHANUMERIC | "_") }
viewpoint_token = @{ "viewpoint" ~ !(ASCII_ALPHANUMERIC | "_") }
variation_token = @{ "variation" ~ !(ASCII_ALPHANUMERIC | "_") }
attribute_token = @{ "attribute" ~ !(ASCII_ALPHANUMERIC | "_") }
interface_token = @{ "interface" ~ !(ASCII_ALPHANUMERIC | "_") }
objective_token = @{ "objective" ~ !(ASCII_ALPHANUMERIC | "_") }
nonunique_token = @{ "nonunique" ~ !(ASCII_ALPHANUMERIC | "_") }
succession_token = @{ "succession" ~ !(ASCII_ALPHANUMERIC | "_") }
terminate_token = @{ "terminate" ~ !(ASCII_ALPHANUMERIC | "_") }
transition_token = @{ "transition" ~ !(ASCII_ALPHANUMERIC | "_") }
timeslice_token = @{ "timeslice" ~ !(ASCII_ALPHANUMERIC | "_") }
protected_token = @{ "protected" ~ !(ASCII_ALPHANUMERIC | "_") }
standard_token = @{ "standard" ~ !(ASCII_ALPHANUMERIC | "_") }
typed_token = @{ "typed" ~ !(ASCII_ALPHANUMERIC | "_") }
class_token = @{ "class" ~ !(ASCII_ALPHANUMERIC | "_") }
constant_token = @{ "constant" ~ !(ASCII_ALPHANUMERIC | "_") }
metadata_token = @{ "metadata" ~ !(ASCII_ALPHANUMERIC | "_") }
language_token = @{ "language" ~ !(ASCII_ALPHANUMERIC | "_") }
snapshot_token = @{ "snapshot" ~ !(ASCII_ALPHANUMERIC | "_") }
parallel_token = @{ "parallel" ~ !(ASCII_ALPHANUMERIC | "_") }
allocate_token = @{ "allocate" ~ !(ASCII_ALPHANUMERIC | "_") }
analysis_token = @{ "analysis" ~ !(ASCII_ALPHANUMERIC | "_") }
abstract_token = @{ "abstract" ~ !(ASCII_ALPHANUMERIC | "_") }
library_token = @{ "library" ~ !(ASCII_ALPHANUMERIC | "_") }
require_token = @{ "require" ~ !(ASCII_ALPHANUMERIC | "_") }
perform_token = @{ "perform" ~ !(ASCII_ALPHANUMERIC | "_") }
exhibit_token = @{ "exhibit" ~ !(ASCII_ALPHANUMERIC | "_") }
include_token = @{ "include" ~ !(ASCII_ALPHANUMERIC | "_") }
satisfy_token = @{ "satisfy" ~ !(ASCII_ALPHANUMERIC | "_") }
binding_token = @{ "binding" ~ !(ASCII_ALPHANUMERIC | "_") }
crosses_token = @{ "crosses" ~ !(ASCII_ALPHANUMERIC | "_") }
message_token = @{ "message" ~ !(ASCII_ALPHANUMERIC | "_") }
package_token = @{ "package" ~ !(ASCII_ALPHANUMERIC | "_") }
private_token = @{ "private" ~ !(ASCII_ALPHANUMERIC | "_") }
variant_token = @{ "variant" ~ !(ASCII_ALPHANUMERIC | "_") }
concern_token = @{ "concern" ~ !(ASCII_ALPHANUMERIC | "_") }
connect_token = @{ "connect" ~ !(ASCII_ALPHANUMERIC | "_") }
default_token = @{ "default" ~ !(ASCII_ALPHANUMERIC | "_") }
defined_token = @{ "defined" ~ !(ASCII_ALPHANUMERIC | "_") }
derived_token = @{ "derived" ~ !(ASCII_ALPHANUMERIC | "_") }
subject_token = @{ "subject" ~ !(ASCII_ALPHANUMERIC | "_") }
ordered_token = @{ "ordered" ~ !(ASCII_ALPHANUMERIC | "_") }
hastype_token = @{ "hastype" ~ !(ASCII_ALPHANUMERIC | "_") }
istype_token = @{ "istype" ~ !(ASCII_ALPHANUMERIC | "_") }
implies_token = @{ "implies" ~ !(ASCII_ALPHANUMERIC | "_") }
comment_token = @{ "comment" ~ !(ASCII_ALPHANUMERIC | "_") }
subsets_token = @{ "subsets" ~ !(ASCII_ALPHANUMERIC | "_") }
render_token = @{ "render" ~ !(ASCII_ALPHANUMERIC | "_") }
expose_token = @{ "expose" ~ !(ASCII_ALPHANUMERIC | "_") }
decide_token = @{ "decide" ~ !(ASCII_ALPHANUMERIC | "_") }
import_token = @{ "import" ~ !(ASCII_ALPHANUMERIC | "_") }
return_token = @{ "return" ~ !(ASCII_ALPHANUMERIC | "_") }
action_token = @{ "action" ~ !(ASCII_ALPHANUMERIC | "_") }
accept_token = @{ "accept" ~ !(ASCII_ALPHANUMERIC | "_") }
assert_token = @{ "assert" ~ !(ASCII_ALPHANUMERIC | "_") }
assign_token = @{ "assign" ~ !(ASCII_ALPHANUMERIC | "_") }
assume_token = @{ "assume" ~ !(ASCII_ALPHANUMERIC | "_") }
locale_token = @{ "locale" ~ !(ASCII_ALPHANUMERIC | "_") }
verify_token = @{ "verify" ~ !(ASCII_ALPHANUMERIC | "_") }
event_token = @{ "event" ~ !(ASCII_ALPHANUMERIC | "_") }
entry_token = @{ "entry" ~ !(ASCII_ALPHANUMERIC | "_") }
false_token = @{ "false" ~ !(ASCII_ALPHANUMERIC | "_") }
frame_token = @{ "frame" ~ !(ASCII_ALPHANUMERIC | "_") }
about_token = @{ "about" ~ !(ASCII_ALPHANUMERIC | "_") }
actor_token = @{ "actor" ~ !(ASCII_ALPHANUMERIC | "_") }
after_token = @{ "after" ~ !(ASCII_ALPHANUMERIC | "_") }
alias_token = @{ "alias" ~ !(ASCII_ALPHANUMERIC | "_") }
while_token = @{ "while" ~ !(ASCII_ALPHANUMERIC | "_") }
until_token = @{ "until" ~ !(ASCII_ALPHANUMERIC | "_") }
first_token = @{ "first" ~ !(ASCII_ALPHANUMERIC | "_") }
merge_token = @{ "merge" ~ !(ASCII_ALPHANUMERIC | "_") }
inout_token = @{ "inout" ~ !(ASCII_ALPHANUMERIC | "_") }
specializes_token = @{ "specializes" ~ !(ASCII_ALPHANUMERIC | "_") }
public_token = @{ "public" ~ !(ASCII_ALPHANUMERIC | "_") }
filter_token = @{ "filter" ~ !(ASCII_ALPHANUMERIC | "_") }
state_token = @{ "state" ~ !(ASCII_ALPHANUMERIC | "_") }
port_token = @{ "port" ~ !(ASCII_ALPHANUMERIC | "_") }
case_token = @{ "case" ~ !(ASCII_ALPHANUMERIC | "_") }
calc_token = @{ "calc" ~ !(ASCII_ALPHANUMERIC | "_") }
send_token = @{ "send" ~ !(ASCII_ALPHANUMERIC | "_") }
then_token = @{ "then" ~ !(ASCII_ALPHANUMERIC | "_") }
flow_token = @{ "flow" ~ !(ASCII_ALPHANUMERIC | "_") }
fork_token = @{ "fork" ~ !(ASCII_ALPHANUMERIC | "_") }
from_token = @{ "from" ~ !(ASCII_ALPHANUMERIC | "_") }
join_token = @{ "join" ~ !(ASCII_ALPHANUMERIC | "_") }
loop_token = @{ "loop" ~ !(ASCII_ALPHANUMERIC | "_") }
part_token = @{ "part" ~ !(ASCII_ALPHANUMERIC | "_") }
true_token = @{ "true" ~ !(ASCII_ALPHANUMERIC | "_") }
view_token = @{ "view" ~ !(ASCII_ALPHANUMERIC | "_") }
bind_token = @{ "bind" ~ !(ASCII_ALPHANUMERIC | "_") }
else_token = @{ "else" ~ !(ASCII_ALPHANUMERIC | "_") }
enum_token = @{ "enum" ~ !(ASCII_ALPHANUMERIC | "_") }
item_token = @{ "item" ~ !(ASCII_ALPHANUMERIC | "_") }
meta_token = @{ "meta" ~ !(ASCII_ALPHANUMERIC | "_") }
null_token = @{ "null" ~ !(ASCII_ALPHANUMERIC | "_") }
when_token = @{ "when" ~ !(ASCII_ALPHANUMERIC | "_") }
exit_token = @{ "exit" ~ !(ASCII_ALPHANUMERIC | "_") }
def_token = @{ "def" ~ !(ASCII_ALPHANUMERIC | "_") }
doc_token = @{ "doc" ~ !(ASCII_ALPHANUMERIC | "_") }
end_token = @{ "end" ~ !(ASCII_ALPHANUMERIC | "_") }
for_token = @{ "for" ~ !(ASCII_ALPHANUMERIC | "_") }
not_token = @{ "not" ~ !(ASCII_ALPHANUMERIC | "_") }
ref_token = @{ "ref" ~ !(ASCII_ALPHANUMERIC | "_") }
rep_token = @{ "rep" ~ !(ASCII_ALPHANUMERIC | "_") }
use_token = @{ "use" ~ !(ASCII_ALPHANUMERIC | "_") }
via_token = @{ "via" ~ !(ASCII_ALPHANUMERIC | "_") }
xor_token = @{ "xor" ~ !(ASCII_ALPHANUMERIC | "_") }
all_token = @{ "all" ~ !(ASCII_ALPHANUMERIC | "_") }
and_token = @{ "and" ~ !(ASCII_ALPHANUMERIC | "_") }
out_token = @{ "out" ~ !(ASCII_ALPHANUMERIC | "_") }
to_token = @{ "to" ~ !(ASCII_ALPHANUMERIC | "_") }
as_token = @{ "as" ~ !(ASCII_ALPHANUMERIC | "_") }
at_token = @{ "at" ~ !(ASCII_ALPHANUMERIC | "_") }
by_token = @{ "by" ~ !(ASCII_ALPHANUMERIC | "_") }
do_token = @{ "do" ~ !(ASCII_ALPHANUMERIC | "_") }
if_token = @{ "if" ~ !(ASCII_ALPHANUMERIC | "_") }
in_token = @{ "in" ~ !(ASCII_ALPHANUMERIC | "_") }
of_token = @{ "of" ~ !(ASCII_ALPHANUMERIC | "_") }
or_token = @{ "or" ~ !(ASCII_ALPHANUMERIC | "_") }
// Delimiters and Operators
forward_curl_brace = @{ "{" }
backward_curl_brace = @{ "}" }
semi_colon = @{ ";" }
double_colon = @{ "::" }
colon = @{ ":" }
wildcard = @{ "*" }
space = @{ " " }
question_mark = @{ "?" }
double_question_mark = @{ "??" }
conjugate_operator = @{ "~" }
conjugation_operator = { "~" }
at_symbol = @{ "@" }
// Markers
individual_marker = { individual_token }
// Keywords - ordered by length (longest first) to avoid prefix matching issues
keyword = @{
verification_token | stakeholder_token | specializes_token | requirement_token | redefines_token
| references_token | individual_token | constraint_token | connection_token | allocation_token
| dependency_token | occurrence_token | rendering_token | viewpoint_token | variation_token
| attribute_token | interface_token | objective_token | nonunique_token | succession_token
| terminate_token | transition_token | timeslice_token | protected_token | standard_token
| metadata_token | language_token | snapshot_token | parallel_token
| allocate_token | analysis_token | abstract_token | library_token | require_token
| constant_token | perform_token | exhibit_token | include_token | satisfy_token | binding_token
| crosses_token | message_token | package_token | private_token | variant_token
| concern_token | connect_token | default_token | defined_token | derived_token
| subject_token | ordered_token | hastype_token | istype_token | implies_token
| comment_token | subsets_token | render_token | expose_token | decide_token
| import_token | return_token | action_token | accept_token | assert_token
| assign_token | assume_token | locale_token | verify_token | event_token
| entry_token | false_token | frame_token | about_token | actor_token
| after_token | alias_token | while_token | until_token | first_token
| merge_token | inout_token | public_token | filter_token | state_token
| port_token | case_token | calc_token | send_token | then_token | flow_token
| fork_token | from_token | join_token | loop_token | part_token | true_token
| view_token | bind_token | else_token | enum_token | item_token | meta_token
| null_token | when_token | exit_token
| def_token | doc_token | end_token | for_token | not_token | ref_token | rep_token
| use_token | via_token | xor_token | all_token | and_token | out_token
| to_token | as_token | at_token | by_token | do_token | if_token | in_token | of_token | or_token
}
// Identifiers
identifier = @{ !keyword ~ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* }
// Multiple tokens
defined_by_token = @{ colon | (defined_token ~ space ~ by_token) }
portion_kind = @{ timeslice_token | snapshot_token }
requirement_constraint_kind = @{ assume_token | require_token }
visibility = @{ public_token | private_token | protected_token }
rendering_def = { rendering_token ~ def_token }
typed_by_token = @{ colon | (typed_token ~ space ~ by_token) }
// Relationship operators (allow both symbol and keyword forms)
specializes_operator = @{ ":>" | specializes_token }
subsets_operator = @{ ":>" | subsets_token }
references_operator = @{ "::>" | references_token }
crosses_operator = @{ "=>" | crosses_token }
redefines_operator = @{ ":>>" | redefines_token }
classification_test_operator = {
hastype_token | istype_token | at_symbol
}
// Control Nodes - extends ActionUsage
control_node = {
merge_node
| decision_node
| join_node
| fork_node
}
control_node_prefix = {
ref_prefix ~ individual_token? ~ portion_kind? ~ usage_extension_keyword*
}
merge_node = {
control_node_prefix ~ merge_token ~ usage_declaration? ~ action_body
}
decision_node = {
control_node_prefix ~ decide_token ~ usage_declaration? ~ action_body
}
join_node = {
control_node_prefix ~ join_token ~ usage_declaration? ~ action_body
}
fork_node = {
control_node_prefix ~ fork_token ~ usage_declaration? ~ action_body
}
// State Subaction Membership - extends FeatureMembership
state_subaction_kind = { entry_token | exit_token | do_token }
state_subaction_membership = { state_subaction_kind ~ identifier ~ semi_colon }
// Transition Feature Membership - extends FeatureMembership
transition_feature_kind = { accept_token | if_token | do_token }
transition_feature_membership = { transition_feature_kind ~ identifier ~ semi_colon }
// Parameter Memberships - extends ParameterMembership
subject_membership = { subject_token ~ identifier ~ semi_colon }
actor_membership = { actor_token ~ identifier ~ semi_colon }
stakeholder_membership = { stakeholder_token ~ identifier ~ semi_colon }
// Feature Memberships
objective_membership = { objective_token ~ identifier ~ semi_colon }
view_rendering_membership = { render_token ~ identifier ~ semi_colon }
// =============================================================================
// Extracted Common Patterns
// These rules improve error messages by naming commonly used patterns
// =============================================================================
// TransitionTarget: the target of a succession/transition
// Matches: "then X" | "if guard then X" | "else X"
transition_target = {
then_token ~ connector_end_member
| guarded_target_succession
| default_target_succession
}
// TypedReference: a reference with optional feature specialization part
// Used for perform/exhibit/satisfy/include patterns
typed_reference = {
owned_reference_subsetting ~ feature_specialization_part?
}
// ReferenceChain: a reference with zero or more feature specializations
// Used for requirement constraints, framed concerns, etc.
reference_chain = {
owned_reference_subsetting ~ feature_specialization*
}
// ActionDeclarationHeader: "action" with optional declaration
// Used in action nodes, perform actions, etc.
action_declaration_header = {
action_usage_keyword ~ usage_declaration?
}
// SuccessionHeader: "succession" with optional declaration
succession_header = {
succession_keyword ~ usage_declaration?
}
// =============================================================================
// Succession and Expose
// Succession keyword
succession_keyword = @{ succession_token }
succession_as_usage = {
usage_prefix
~ succession_header?
~ first_token
~ connector_end_member
~ transition_target
~ definition_body
}
// Expose - similar to Import but for exposing elements in views
expose_prefix = { visibility? ~ expose_token }
// MembershipExpose: expose a specific member
membership_expose = { expose_prefix ~ imported_membership }
// NamespaceExpose: expose all members of a namespace
namespace_expose = { expose_prefix ~ imported_namespace }
// Main expose rule - union of membership and namespace exposes
// IMPORTANT: namespace_expose must come first since it's more specific
// (membership_expose would partially match namespace patterns)
// filter_package? is optional and applies to both expose types
expose = {
(namespace_expose | membership_expose)
~ filter_package?
~ relationship_body
}
// Port and Conjugation
// Per official grammar, PortDefinition implicitly creates a ConjugatedPortDefinition
// The ~ prefix in type references indicates a conjugated port typing
variant_membership = { variant_token ~ variant_usage_element }
conjugated_port_definition = {
occurrence_definition_prefix ~ port_token ~ def_token ~ conjugate_operator ~ definition_declaration ~ definition_body
}
conjugated_port_typing = { port_token ~ identifier ~ colon ~ conjugate_operator ~ identifier ~ semi_colon }
// Requirement Constraint Memberships
requirement_constraint_membership = { require_token ~ identifier ~ semi_colon }
framed_concern_membership = { frame_token ~ identifier ~ semi_colon }
requirement_verification_membership = { verify_token ~ identifier ~ semi_colon }
// Terminate Action
terminate_action_usage = { terminate_token ~ identifier ~ semi_colon }
// Port Definitions and Conjugation
// Package
package = {
prefix_metadata?
~ package_declaration
~ package_body
}
library_package = {
standard_token?
~ library_token
~ prefix_metadata?
~ package_declaration
~ package_body
}
package_declaration = { package_token ~ identification? }
package_body = { semi_colon | ( forward_curl_brace ~ package_body_items ~ backward_curl_brace ) }
package_body_items = { package_body_element* }
// package_body_element is now defined in Model Entry Point section
usage_member = { visibility? ~ usage_element }
relationship_member_element = { visibility? ~ prefix_metadata? ~ dependency }
element_filter_member = { visibility? ~ filter_token ~ owned_expression ~ semi_colon }
// Expressions
expression_body = {
forward_curl_brace ~ expression_body_part? ~ backward_curl_brace
| semi_colon
}
expression_body_part = {
visible_annotating_member* ~ (parameter_binding_with_terminator)+ ~ non_occurrence_usage_member* ~ owned_expression
| visible_annotating_member* ~ (parameter_binding_with_terminator)+
| visible_annotating_member* ~ non_occurrence_usage_member* ~ owned_expression
| visible_annotating_member* ~ owned_expression
}
parameter_binding_with_terminator = {
parameter_binding ~ semi_colon?
}
parameter_binding = {
feature_direction_kind ~ ref_token? ~ identifier? ~ ((specializes_operator | colon) ~ owned_feature_typing)? ~ (forward_curl_brace ~ visible_annotating_member* ~ backward_curl_brace)?
| ref_token? ~ identifier ~ (specializes_operator | colon) ~ owned_feature_typing ~ (forward_curl_brace ~ visible_annotating_member* ~ backward_curl_brace)?
}
// =============================================================================
// EXPRESSION RULES
// Most expression rules come from kerml_expressions.pest (shared with KerML)
// Below are SysML-specific rules and token definitions
// =============================================================================
// Equality operator tokens
equality_operator = {
"===" | "!==" | "==" | "!="
}
// Atomic operators with word boundaries
as_operator = @{ as_token }
meta_operator = @{ meta_token }
// Classification Expressions
classification_expression = {
metadata_reference ~ "@@" ~ type_reference_member
| metadata_reference ~ meta_operator ~ type_result_member
| classification_test_operator ~ type_reference_member
| as_operator ~ type_result_member
| relational_expression ~ (
("@@" ~ type_reference_member)
| (meta_operator ~ type_result_member)
| (classification_test_operator ~ type_reference_member)
| (as_operator ~ type_result_member)
)?
}
type_reference_member = {
type_reference
}
type_reference = {
qualified_name
}
type_result_member = {
type_result
}
type_result = {
qualified_name
}
metadata_reference = {
qualified_name | metadata_token
}
// Relational operator tokens
relational_operator = {
"<=" | ">=" | "<" | ">"
}
// Arithmetic operator tokens
additive_operator = {
"+" | "-"
}
multiplicative_operator = {
"*" | "/" | "%"
}
exponentiation_operator = {
"**" | "^"
}
unary_operator = {
"+" | "-" | "~" | "not"
}
// Extent Expressions
extent_expression = {
"all" ~ !(ASCII_ALPHANUMERIC | "_" | "(") ~ type_result_member
| primary_expression
}
// Primary Expressions
primary_expression = {
base_expression
~ (
"@" ~ "[" ~ qualified_name ~ "]" // measurement reference (unit)
| "." ~ feature_chain_member ~ argument_list? // feature chain with optional method call
| "#" ~ "(" ~ sequence_expression ~ ")" // indexing with #
| "[" ~ sequence_expression ~ "]" // indexing with []
| "->" ~ reference_typing ~ (
expression_body_member
| function_reference_member
| argument_list
) // invocation
| "." ~ expression_body_member // collect
| ".?" ~ expression_body_member // select
)*
}
// Base Expressions
base_expression = {
null_expression
| literal_expression
| instantiation_expression
| invocation_expression
| feature_reference_expression
| expression_body
| "(" ~ sequence_expression? ~ ")"
}
instantiation_expression = {
"new" ~ owned_feature_typing ~ argument_list?
}
null_expression = @{
"null" ~ !(ASCII_ALPHANUMERIC | "_")
}
literal_expression = {
literal
}
feature_reference_expression = {
qualified_name
}
metadata_access_expression = {
"metadata" ~ identifier
}
invocation_expression = {
owned_feature_typing ~ argument_list
}
feature_chain_member = {
identifier | quoted_name
}
// Sequence Expressions
sequence_expression = {
owned_expression ~ ("," ~ owned_expression)*
}
reference_typing = {
identifier
}
// Expression Body
body_expression = {
expression_body
}
expression_body_member = {
expression_body
}
function_reference_member = {
identifier
}
argument_list = {
"(" ~ (named_argument_list | positional_argument_list)? ~ ")"
}
positional_argument_list = {
argument_member ~ ("," ~ argument_member)*
}
argument_member = {
argument
}
argument = {
argument_value
}
named_argument_list = {
named_argument_member ~ ("," ~ named_argument_member)*
}
named_argument_member = {
named_argument
}
named_argument = {
parameter_redefinition ~ "=" ~ argument_value
}
parameter_redefinition = {
feature_reference
}
argument_value = {
owned_expression
}
// Literal values (basic support)
literal = {
string_value
| numeric_value
| boolean_value
| null_literal
}
null_literal = @{ "null" ~ !(ASCII_ALPHANUMERIC | "_") }
string_value = @{ "\"" ~ (!"\"" ~ ANY)* ~ "\"" }
numeric_value = @{
"-"? ~ (ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)? | "." ~ ASCII_DIGIT+) ~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)?
}
boolean_value = @{ ("true" | "false") ~ !(ASCII_ALPHANUMERIC | "_") }
alias_member_element = {
visibility?
~ alias_token
~ identification?
~ for_token
~ element_reference
~ relationship_body
}
definition_member_element = { visibility? ~ definition_element }
// Definition Structure
basic_definition_prefix = {
abstract_token
| variation_token
}
definition_extension_keyword = { prefix_metadata_member }
definition_prefix = {
basic_definition_prefix? ~ definition_extension_keyword*
}
definition_suffix = {
definition_declaration ~ definition_body
}
definition_declaration = {
identification? ~ (subclassification_part | redefinition_part)?
}
// Function-like definition declaration (for calc def, action def, etc.)
// Supports parameter lists and return type
// Note: return_type only makes sense when parameters are present; otherwise `:>` is specialization
function_definition_declaration = {
identification? ~ function_parameter_list ~ return_type? ~ (subclassification_part | redefinition_part)?
| identification? ~ (subclassification_part | redefinition_part)?
}
function_parameter_list = {
"(" ~ (function_parameter ~ ("," ~ function_parameter)*)? ~ ")"
}
function_parameter = {
(in_token | out_token | inout_token)? ~ (identifier | quoted_name) ~ feature_specialization_part?
}
return_type = {
subsets_operator ~ feature_reference
}
definition_body = {
";"
| forward_curl_brace ~ definition_body_items ~ backward_curl_brace
}
definition_body_items = { definition_body_item* }
definition_body_item = {
import
| alias_member_element
| visible_annotating_member
| relationship_member_element
| definition_member
| variant_usage_member
| non_occurrence_usage_member
| empty_succession_member? ~ occurrence_usage_member
}
definition_member = {
visibility? ~ definition_element
}
variant_usage_member = { visibility? ~ variant_membership }
non_occurrence_usage_member = { visibility? ~ non_occurrence_usage_element }
occurrence_usage_member = { visibility? ~ occurrence_usage_element }
// Empty succession for occurrence ordering
empty_succession_member = { empty_succession }
empty_succession = {
"then" ~ multiplicity_source_end_member ~ empty_target_end_member
}
multiplicity_source_end_member = { multiplicity_source_end }
multiplicity_source_end = {
owned_multiplicity?
}
empty_target_end_member = { empty_target_end }
empty_target_end = { "" }
// Definition and Usage Elements
definition_element = {
package
| library_package
| attribute_definition
| enumeration_definition
| occurrence_definition
| individual_definition
| item_definition
| metadata_definition
| part_definition
| connection_definition
| flow_definition
| interface_definition
| allocation_definition
| port_definition
| action_definition
| calculation_definition
| state_definition
| constraint_definition
| requirement_definition
| concern_definition
| case_definition
| analysis_case_definition
| verification_case_definition
| use_case_definition
| view_definition
| viewpoint_definition
| rendering_definition
| extended_definition
}
// Placeholder definitions for each type (to be implemented incrementally)
attribute_definition = {
definition_prefix ~ attribute_token ~ def_token ~ definition_suffix
}
enumeration_definition = {
prefix_metadata? ~ enum_token ~ def_token ~ definition_declaration ~ enumeration_body
}
enumeration_body = {
";"
| forward_curl_brace ~ enumeration_items ~ backward_curl_brace
}
enumeration_items = {
(annotating_member | enumeration_usage_member)*
}
enumeration_usage_member = {
visibility? ~ enumerated_value
}
enumerated_value = {
prefix_metadata? ~ enum_token? ~ usage_suffix
}
// Occurrence keywords
occurrence_keyword = { occurrence_token }
occurrence_def_keyword = { occurrence_token ~ def_token }
// Empty multiplicity for individual definitions
empty_multiplicity_member = { empty_multiplicity }
empty_multiplicity = { "" }
// Occurrence definition prefix
occurrence_definition_prefix = {
basic_definition_prefix?
~ ("individual" ~ empty_multiplicity_member)?
~ definition_extension_keyword*
}
occurrence_definition = {
occurrence_definition_prefix ~ occurrence_def_keyword ~ definition_declaration ~ definition_body
}
individual_definition = {
basic_definition_prefix?
~ individual_token
~ empty_multiplicity_member
~ definition_extension_keyword*
~ def_token
~ definition_declaration
~ definition_body
}
// Item keywords
item_keyword = { item_token }
item_def_keyword = { item_token ~ def_token }
item_usage_keyword = { item_token }
item_definition = {
occurrence_definition_prefix ~ item_def_keyword ~ definition_declaration ~ definition_body
}
// Part keywords
part_keyword = { part_token }
part_def_keyword = { part_token ~ def_token }
part_usage_keyword = { part_token }
part_definition = {
occurrence_definition_prefix ~ part_def_keyword ~ definition_declaration ~ definition_body
}
// Connection keywords
connection_keyword = { connection_token }
connection_def_keyword = { connection_token ~ def_token }
connector_keyword = { connect_token }
connection_usage_keyword = { connection_token }
connection_definition = {
occurrence_definition_prefix ~ connection_def_keyword ~ definition_declaration ~ definition_body
}
// Flow keywords
flow_keyword = { flow_token }
flow_def_keyword = { flow_token ~ def_token }
flow_definition = {
occurrence_definition_prefix ~ flow_def_keyword ~ definition_declaration ~ definition_body
}
// Interface keywords
interface_keyword = { interface_token }
interface_def_keyword = { interface_token ~ def_token }
interface_definition = {
occurrence_definition_prefix ~ interface_def_keyword ~ definition_declaration ~ interface_body
}
interface_body = {
semi_colon
| forward_curl_brace ~ interface_body_item* ~ backward_curl_brace
| connector_keyword ~ connector_part ~ semi_colon
}
interface_body_item = {
import
| alias_member_element
| visible_annotating_member
| definition_member
| variant_usage_member
| interface_non_occurrence_usage_member
| empty_succession_member? ~ interface_occurrence_usage_member
}
interface_non_occurrence_usage_member = {
visibility? ~ interface_non_occurrence_usage_element
}
interface_non_occurrence_usage_element = {
reference_usage
| attribute_usage
| enumeration_usage
| binding_connector_as_usage
| succession_as_usage
}
interface_occurrence_usage_member = {
visibility? ~ interface_occurrence_usage_element
}
interface_occurrence_usage_element = {
default_interface_end
| structure_usage_element
| behavior_usage_element
}
default_interface_end = {
"end" ~ usage_declaration? ~ usage_completion
}
// Interface Usages
interface_usage_keyword = { interface_keyword }
interface_usage = {
occurrence_usage_prefix ~ interface_usage_keyword ~ interface_usage_declaration ~ interface_body
}
// InterfaceUsageDeclaration per spec:
// UsageDeclaration ValuePart? ('connect' InterfacePart)?
// | InterfacePart
//
// Ordering matters for PEG parsing:
// 1. interface_part - handles shorthand "interface a.b to c.d" (no name, no connect keyword)
// 2. usage_declaration? ~ connector_keyword ~ interface_part - handles "connect a to b" and "name connect a to b"
// 3. usage_declaration ~ value_part? - handles "name = value" cases without connector
interface_usage_declaration = {
interface_part
| usage_declaration? ~ connector_keyword ~ interface_part
| usage_declaration ~ value_part?
}
interface_part = {
binary_interface_part
| nary_interface_part
}
binary_interface_part = {
interface_end_member ~ to_token ~ interface_end_member
}
nary_interface_part = {
"(" ~ interface_end_member ~ "," ~ interface_end_member ~ ("," ~ interface_end_member)* ~ ")"
}
interface_end_member = {
interface_end
}
// Interface end per spec: optional multiplicity, optional local name with references,
// and the target feature. The (identifier references_operator) pattern must be guarded
// to avoid consuming an identifier that's part of a feature chain.
// Also supports crosses_operator (=>) for boundary crossing connections.
interface_end = {
owned_cross_multiplicity_member? ~ (identifier ~ (references_operator | crosses_operator) ~ owned_reference_subsetting | owned_reference_subsetting)
}
allocation_definition = {
occurrence_definition_prefix ~ allocation_token ~ def_token ~ definition_suffix
}
port_definition = {
occurrence_definition_prefix ~ port_token ~ def_token ~ definition_declaration ~ definition_body
}
// Action keywords
action_keyword = { action_token }
action_def_keyword = { action_token ~ def_token }
assignment_operator = @{ ":=" }
// State Keywords
state_keyword = { state_token }
state_def_keyword = { state_token ~ def_token }
// State Definition
state_definition = {
occurrence_definition_prefix ~ state_def_keyword ~ definition_declaration ~ state_def_body
}
state_def_body = {
";"
| parallel_marker? ~ forward_curl_brace ~ state_body_part ~ backward_curl_brace
}
parallel_marker = { parallel_token }
state_body_part = {
state_body_item*
}
state_body_item = {
import
| alias_member_element
| visible_annotating_member
| definition_member
| variant_usage_member
| non_occurrence_usage_member
| empty_succession_member? ~ structure_usage_member
| empty_succession_member? ~ behavior_usage_member ~ target_transition_usage_member*
| transition_usage_member
| entry_action_member ~ entry_transition_member*
| do_action_member
| exit_action_member
}
// State Subaction Members
entry_action_member = {
member_prefix ~ entry_action_kind ~ state_action_usage
}
entry_action_kind = { entry_token }
do_action_member = {
member_prefix ~ do_action_kind ~ state_action_usage
}
do_action_kind = { do_token }
exit_action_member = {
member_prefix ~ exit_action_kind ~ state_action_usage
}
exit_action_kind = { exit_token }
entry_transition_member = {
member_prefix ~ (guarded_target_succession | then_token ~ transition_succession) ~ semi_colon
}
// State action usage can be:
// - action keyword with body
// - semicolon (empty)
// - qualified name reference
// - assign action (issue #623)
// - send node (for entry/do/exit actions)
// - accept node (for entry/do/exit actions)
state_action_usage = {
action_keyword ~ (identifier ~ semi_colon | usage_declaration? ~ action_body)
| identifier ~ (semi_colon | action_body)
| send_node_declaration ~ semi_colon
| accept_node_declaration ~ semi_colon
| assignment_node_declaration ~ semi_colon
| ";"
| qualified_name ~ semi_colon
}
empty_action_usage = {
""
}
performed_action_usage = {
perform_action_usage_declaration
| accept_node_declaration
| send_node_declaration
| assignment_node_declaration
}
transition_usage_member = {
member_prefix ~ transition_usage
}
target_transition_usage_member = {
member_prefix ~ target_transition_usage
}
action_definition = {
occurrence_definition_prefix ~ action_def_keyword ~ function_definition_declaration ~ action_body
}
action_body = {
";"
| forward_curl_brace ~ action_body_item* ~ backward_curl_brace
}
action_body_item = {
import
| alias_member_element
| visible_annotating_member
| definition_member
| variant_usage_member
| directed_parameter_member
| non_occurrence_usage_member
| empty_succession_member? ~ structure_usage_member
| initial_node_member ~ target_succession_member*
| empty_succession_member? ~ (behavior_usage_member | action_node_member) ~ target_succession_member*
| guarded_succession_member
}
// Directed parameter member: in/out/inout name :type = value;
// This is a shorthand for in/out/inout attribute name :type = value
directed_parameter_member = {
member_prefix ~ feature_direction_kind ~ attribute_token? ~ usage_suffix
}
structure_usage_member = {
visibility? ~ structure_usage_element
}
behavior_usage_member = {
visibility? ~ behavior_usage_element
}
initial_node_member = {
member_prefix ~ first_token ~ feature_reference ~ relationship_body
}
member_prefix = {
visibility?
}
action_node_member = {
member_prefix ~ action_node
}
// Action Nodes
action_node = {
send_node
| accept_node
| assignment_node
| if_node
| while_loop_node
| for_loop_node
| terminate_node
| control_node
}
action_node_usage_declaration = {
action_usage_keyword ~ usage_declaration?
}
action_node_prefix = {
occurrence_usage_prefix ~ action_node_usage_declaration?
}
// Accept Node
accept_node = {
occurrence_usage_prefix ~ accept_node_declaration ~ action_body
}
accept_node_declaration = {
action_node_usage_declaration? ~ accept_token ~ accept_parameter_part
}
accept_parameter_part = {
payload_parameter_member ~ (via_token ~ node_parameter_member)?
}
payload_parameter_member = {
payload_parameter
}
// Note: Order matters (PEG ordered choice) - check trigger pattern first since it's more specific
// Otherwise `accept sig after 10` would match `sig` as payload and fail on `after`
payload_parameter = {
identification? ~ payload_feature_specialization_part? ~ trigger_value_part
| payload
}
trigger_value_part = {
trigger_feature_value
}
trigger_feature_value = {
trigger_expression
}
trigger_expression = {
time_trigger_kind ~ argument_member
| change_trigger_kind ~ argument_expression_member
}
time_trigger_kind = {
at_token | after_token
}
change_trigger_kind = {
when_token
}
argument_expression_member = {
argument_expression
}
argument_expression = {
argument_expression_value
}
argument_expression_value = {
owned_expression_reference
}
node_parameter_member = {
node_parameter
}
node_parameter = {
feature_binding
}
feature_binding = {
owned_expression
}
empty_parameter_member = {
empty_usage
}
// Send Node
send_node = {
occurrence_usage_prefix ~ action_node_usage_declaration? ~ send_token ~ (
action_body
| (node_parameter_member ~ sender_receiver_part? | empty_parameter_member ~ sender_receiver_part) ~ action_body
)
}
send_node_declaration = {
action_node_usage_declaration? ~ send_token ~ node_parameter_member ~ sender_receiver_part?
}
sender_receiver_part = {
via_token ~ node_parameter_member ~ (to_token ~ node_parameter_member)?
| empty_parameter_member ~ to_token ~ node_parameter_member
}
// Assignment Node
assignment_node = {
occurrence_usage_prefix ~ assignment_node_declaration ~ action_body
}
assignment_node_declaration = {
assign_token ~ assignment_target_chain ~ assignment_operator ~ node_parameter_member
| action_keyword ~ usage_declaration? ~ assign_token ~ assignment_target_chain ~ assignment_operator ~ node_parameter_member
}
// Assignment target is a chain of identifiers separated by dots
assignment_target_chain = {
feature_chain_member ~ ("." ~ feature_chain_member)*
}
assignment_target_member = {
target_parameter
}
target_parameter = {
(target_binding ~ ".")? ~ target_feature_member
}
target_binding = {
target_expression
}
target_expression = {
base_expression ~ (
("." ~ feature_chain_member)?
~ (
"[" ~ sequence_expression ~ "]"
| "->" ~ reference_typing ~ (expression_body_member | function_reference_member | argument_list)
| "." ~ expression_body_member
| ".?" ~ expression_body_member
)
)*
}
target_feature_member = {
target_feature
}
target_feature = {
target_accessed_feature_member
}
target_accessed_feature_member = {
empty_usage
}
empty_usage = {
""
}
// Expression Parameter
expression_parameter_member = {
owned_expression
}
// If Node
if_node = {
action_node_prefix ~ if_token ~ expression_parameter_member ~ action_body_parameter_member ~ (else_token ~ (action_body_parameter_member | if_node_parameter_member))?
}
action_body_parameter_member = {
action_body_parameter
}
action_body_parameter = {
action_declaration_header? ~ forward_curl_brace ~ action_body_item* ~ backward_curl_brace
}
if_node_parameter_member = {
if_node
}
// While Loop Node
while_loop_node = {
action_node_prefix ~ (
while_token ~ expression_parameter_member
| loop_token ~ empty_parameter_member
) ~ action_body_parameter_member ~ (until_token ~ expression_parameter_member ~ semi_colon)?
}
// For Loop Node
for_loop_node = {
action_node_prefix ~ for_token ~ for_variable_declaration_member ~ in_token ~ node_parameter_member ~ action_body_parameter_member
}
for_variable_declaration_member = {
for_variable_declaration
}
for_variable_declaration = {
usage_declaration
}
// Terminate Node
terminate_node = {
occurrence_usage_prefix ~ action_node_usage_declaration? ~ terminate_token ~ (action_body | node_parameter_member ~ action_body)
}
target_succession_member = {
member_prefix ~ action_target_succession
}
// ActionTargetSuccession = TargetSuccession | GuardedTargetSuccession | DefaultTargetSuccession
// With UsageBody (;) at the end
action_target_succession = {
(target_succession | guarded_target_succession | default_target_succession) ~ usage_body
}
// TargetSuccession: source end, then, target end (basic "then X")
target_succession = {
multiplicity_source_end_member ~ then_token ~ connector_end_member
}
// GuardedTargetSuccession: "if <expr> then <target>"
guarded_target_succession = {
empty_parameter_member ~ guard_expression_member ~ then_token ~ transition_succession_member
}
// DefaultTargetSuccession: "else <target>"
default_target_succession = {
empty_parameter_member ~ else_token ~ transition_succession_member
}
guarded_succession_member = {
guarded_target_succession
}
// Domain-specific usage keywords that should not be matched as guarded successions
domain_usage_keyword = @{ (satisfy_token | perform_token | exhibit_token | include_token) }
// Calculation Keywords
calculation_keyword = { calc_token }
calculation_def_keyword = { calc_token ~ def_token }
// Calculation Definition
calculation_definition = {
occurrence_definition_prefix ~ calculation_def_keyword ~ function_definition_declaration ~ calculation_body
}
calculation_body = {
";"
| forward_curl_brace ~ calculation_body_part ~ backward_curl_brace
}
calculation_body_part = {
calculation_body_item* ~ result_expression_member?
}
calculation_body_item = {
return_parameter_member
| visible_annotating_member
| parameter_binding ~ semi_colon
| import
| alias_member_element
| definition_member
| variant_usage_member
| non_occurrence_usage_member
| structure_usage_member
| behavior_usage_member
}
return_parameter_member = {
member_prefix ~ return_token ~ attribute_token? ~ (identification ~ feature_specialization_part? | feature_specialization_part)? ~ (value_part | usage_body)?
}
result_expression_member = {
member_prefix ~ owned_expression
}
// Requirement Keywords
requirement_keyword = { requirement_token }
requirement_def_keyword = { requirement_token ~ def_token }
// Requirement Definition
requirement_definition = {
occurrence_definition_prefix ~ requirement_def_keyword ~ definition_declaration ~ requirement_body
}
requirement_body = {
";"
| forward_curl_brace ~ requirement_body_item* ~ backward_curl_brace
}
requirement_body_item = {
definition_body_item
| subject_member
| requirement_constraint_member
| framed_concern_member
| requirement_verification_member
| actor_member
| stakeholder_member
}
subject_member = {
member_prefix ~ subject_usage
}
subject_usage = {
"subject" ~ usage_extension_keyword* ~ usage_suffix
}
requirement_constraint_member = {
member_prefix ~ requirement_constraint_kind ~ requirement_constraint_usage
}
requirement_constraint_usage = {
owned_reference_subsetting ~ feature_specialization* ~ calculation_body
| (usage_extension_keyword* ~ constraint_usage_keyword | usage_extension_keyword+)
~ constraint_usage_declaration ~ calculation_body
}
framed_concern_member = {
member_prefix ~ framed_concern_kind ~ framed_concern_usage
}
framed_concern_kind = {
"frame"
}
framed_concern_usage = {
owned_reference_subsetting ~ feature_specialization* ~ requirement_body
| (usage_extension_keyword* ~ concern_usage_keyword | usage_extension_keyword+)
~ constraint_usage_declaration ~ calculation_body
}
actor_member = {
member_prefix ~ actor_usage
}
actor_usage = {
actor_token ~ usage_extension_keyword* ~ usage_suffix
}
stakeholder_member = {
member_prefix ~ stakeholder_usage
}
stakeholder_usage = {
stakeholder_token ~ usage_extension_keyword* ~ usage_suffix
}
requirement_verification_member = {
member_prefix ~ verify_token ~ requirement_verification_usage
}
requirement_verification_usage = {
owned_reference_subsetting ~ feature_specialization* ~ requirement_body
| (usage_extension_keyword* ~ requirement_usage_keyword | usage_extension_keyword+)
~ constraint_usage_declaration ~ requirement_body
}
// Concern Keywords
concern_keyword = { concern_token }
concern_def_keyword = { concern_token ~ def_token }
// Concern Definition
concern_definition = {
occurrence_definition_prefix ~ concern_def_keyword ~ definition_declaration ~ requirement_body
}
// Case Keywords
case_keyword = { case_token }
case_def_keyword = { case_token ~ def_token }
// Case Definition
case_definition = {
occurrence_definition_prefix ~ case_def_keyword ~ definition_declaration ~ case_body
}
case_body = {
";"
| forward_curl_brace ~ case_body_item* ~ result_expression_member? ~ backward_curl_brace
}
case_body_item = {
objective_member
| subject_member
| actor_member
| case_calculation_body_item
| visible_annotating_member
}
case_calculation_body_item = {
case_action_body_item
| return_parameter_member
}
case_action_body_item = {
initial_node_member ~ target_succession_member*
| empty_succession_member? ~ (behavior_usage_member | action_node_member) ~ target_succession_member*
| guarded_succession_member
| import
| alias_member_element
| definition_member
| variant_usage_member
| non_occurrence_usage_member
| structure_usage_member
}
objective_member = {
member_prefix ~ objective_token ~ objective_requirement_usage
}
objective_requirement_usage = {
usage_extension_keyword* ~ constraint_usage_declaration ~ requirement_body
}
// Analysis Case Keywords
analysis_keyword = { analysis_token }
// Analysis Case Definition
analysis_case_definition = {
occurrence_definition_prefix ~ analysis_keyword ~ (case_def_keyword | def_token) ~ definition_declaration ~ case_body
}
// Verification Case Keywords
verification_keyword = { verification_token }
// Verification Case Definition
verification_case_definition = {
occurrence_definition_prefix ~ verification_keyword ~ (case_def_keyword | def_token) ~ definition_declaration ~ case_body
}
// View Keywords
view_keyword = { view_token }
view_def_keyword = { view_token ~ def_token }
// View Definition
view_definition = {
occurrence_definition_prefix ~ view_def_keyword ~ ("<" ~ identifier ~ ">")? ~ definition_declaration ~ view_definition_body
}
view_definition_body = {
";"
| forward_curl_brace ~ view_definition_body_item* ~ backward_curl_brace
}
view_definition_body_item = {
definition_body_item
| element_filter_member
| view_rendering_member
}
view_rendering_member = {
member_prefix ~ render_token ~ view_rendering_usage
}
view_rendering_usage = {
owned_reference_subsetting ~ feature_specialization* ~ usage_body
| (prefix_metadata? ~ rendering_token | prefix_metadata) ~ usage_suffix
}
// Use Case Keywords
use_case_keyword = { use_token ~ case_token }
use_case_def_keyword = { use_token ~ case_token ~ def_token }
// Use Case Definition
use_case_definition = {
occurrence_definition_prefix ~ use_case_def_keyword ~ definition_declaration ~ case_body
}
// Viewpoint Keywords
viewpoint_keyword = { viewpoint_token }
viewpoint_def_keyword = { viewpoint_token ~ def_token }
// Viewpoint Definition
viewpoint_definition = {
occurrence_definition_prefix ~ viewpoint_def_keyword ~ definition_declaration ~ requirement_body
}
// Rendering Definition
rendering_definition = {
occurrence_definition_prefix ~ rendering_def ~ definition_suffix
}
extended_definition = {
basic_definition_prefix? ~ definition_extension_keyword+ ~ def_token ~ definition_suffix
}
usage_element = {
non_occurrence_usage_element
| occurrence_usage_element
}
// Usages
// Use negative lookahead to ensure direction kinds are complete words
// This prevents "in" from matching the start of "interface"
feature_direction_kind = @{ inout_token | in_token | out_token }
ref_prefix = {
feature_direction_kind?
~ derived_token?
~ basic_definition_prefix?
~ constant_token?
}
reference = { ref_token }
basic_usage_prefix = {
ref_prefix ~ reference?
}
end_usage_prefix = {
end_token ~ owned_crossing_feature_member?
}
usage_extension_keyword = { prefix_metadata_member }
unextended_usage_prefix = {
end_usage_prefix
| basic_usage_prefix
}
owned_crossing_feature_member = { owned_crossing_feature }
// Usage keywords that can follow 'end' - used for negative lookahead
end_usage_keyword = {
item_token | part_token | port_token | connection_token | interface_token
| flow_token | action_token | state_token | constraint_token
| requirement_token | occurrence_token | attribute_token | ref_token
}
owned_crossing_feature = {
!end_usage_keyword ~ basic_usage_prefix? ~ usage_declaration
}
usage_prefix = {
unextended_usage_prefix ~ usage_extension_keyword*
}
usage_suffix = {
usage_declaration? ~ usage_completion
}
// Occurrence usage keyword
occurrence_usage_keyword = { occurrence_keyword }
// Occurrence usage prefix
occurrence_usage_prefix = {
(end_usage_prefix ~ usage_extension_keyword*
| basic_usage_prefix
~ individual_marker?
~ portion_kind?
~ usage_extension_keyword*)
}
usage_declaration = { feature_declaration }
usage_completion = {
value_part? ~ usage_body
}
usage_body = { definition_body }
value_part = { feature_value }
feature_value = {
("="
| ":="
| "default" ~ ("=" | ":=")?
)
~ owned_expression
}
// Reference Usages
default_reference_usage = {
end_token?
~ ref_prefix
~ usage_suffix
}
reference_usage = {
end_token ~ ref_prefix ~ "ref" ~ usage_suffix
| ref_prefix ~ "ref" ~ usage_suffix
}
variant_reference = {
owned_reference_subsetting
~ feature_specialization*
~ usage_body
}
// Body Elements
non_occurrence_usage_element = {
metadata_usage
| reference_usage
| attribute_usage
| enumeration_usage
| binding_connector_as_usage
| succession_as_usage
| extended_usage
| default_reference_usage
}
occurrence_usage_element = {
structure_usage_element
| behavior_usage_element
}
structure_usage_element = {
occurrence_usage
| individual_usage
| portion_usage
| event_occurrence_usage
| item_usage
| part_usage
| view_usage
| rendering_usage
| port_usage
| connection_usage
| interface_usage
| allocation_usage
| allocate_usage
| message
| flow_usage
| succession_flow_usage
}
behavior_usage_element = {
action_usage
| calculation_usage
| state_usage
| constraint_usage
| concern_usage
| case_usage
| analysis_case_usage
| verification_case_usage
| use_case_usage
| viewpoint_usage
| perform_action_usage
| exhibit_state_usage
| include_use_case_usage
| assert_constraint_usage
| satisfy_requirement_usage
| requirement_usage
}
variant_usage_element = {
variant_reference
| reference_usage
| attribute_usage
| binding_connector_as_usage
| succession_as_usage
| occurrence_usage
| individual_usage
| portion_usage
| event_occurrence_usage
| item_usage
| part_usage
| view_usage
| rendering_usage
| port_usage
| connection_usage
| interface_usage
| allocation_usage
| message
| flow_usage
| succession_flow_usage
| behavior_usage_element
}
// Placeholder usage rules (to be implemented incrementally)
attribute_usage = {
usage_prefix ~ attribute_token ~ usage_suffix
}
enumeration_usage = {
usage_prefix ~ enum_token ~ usage_suffix
}
// Binding connector keywords
binding_keyword = { binding_token }
binding_connector_as_usage = {
usage_prefix
~ (binding_keyword ~ usage_declaration?)?
~ bind_token
~ connector_end_member
~ "="
~ connector_end_member
~ definition_body
}
extended_usage = {
unextended_usage_prefix ~ usage_extension_keyword+ ~ usage_suffix
}
occurrence_usage = {
occurrence_usage_prefix ~ occurrence_usage_keyword ~ usage_declaration? ~ usage_completion
}
individual_usage = {
basic_usage_prefix ~ individual_token ~ usage_extension_keyword* ~ usage_declaration? ~ usage_completion
}
portion_usage = {
basic_usage_prefix ~ ("individual")? ~ portion_kind ~ usage_extension_keyword* ~ usage_declaration? ~ usage_completion
}
event_occurrence_usage = {
occurrence_usage_prefix ~ event_token
~ (owned_reference_subsetting ~ feature_specialization_part?
| occurrence_usage_keyword ~ usage_declaration?)
~ usage_completion
}
item_usage = {
occurrence_usage_prefix ~ item_usage_keyword ~ usage_declaration? ~ usage_completion
}
part_usage = {
occurrence_usage_prefix ~ part_usage_keyword ~ usage_declaration? ~ usage_completion
}
// View Usage
view_usage_keyword = { view_keyword }
view_usage = {
occurrence_usage_prefix ~ view_usage_keyword ~ usage_declaration? ~ value_part? ~ view_body
}
view_body = {
";"
| forward_curl_brace ~ view_body_item* ~ backward_curl_brace
}
view_body_item = {
definition_body_item
| element_filter_member
| expose
| view_rendering_member
}
// Rendering Usage
rendering_usage = {
occurrence_usage_prefix ~ rendering_token ~ usage_suffix
}
// Port keywords
port_keyword = { port_token }
port_usage_keyword = { port_token }
port_usage = {
occurrence_usage_prefix ~ port_usage_keyword ~ usage_declaration? ~ usage_completion
}
// Connector elements
connector_end_member = { connector_end }
connector_end = {
owned_cross_multiplicity_member? ~ connector_end_reference
}
connector_end_reference = {
owned_feature_chain
| identifier ~ references_operator ~ (owned_feature_chain | feature_reference)
| quoted_name ~ references_operator ~ (owned_feature_chain | feature_reference)
| feature_reference
}
owned_cross_multiplicity_member = { owned_cross_multiplicity }
owned_cross_multiplicity = { owned_multiplicity }
// Connection usage and connector parts
connection_usage = {
occurrence_usage_prefix
~ (connection_usage_keyword ~ usage_declaration? ~ value_part?
~ (connector_keyword ~ connector_part)?
| connector_keyword ~ connector_part)
~ usage_body
}
connector_part = {
binary_connector_part
| nary_connector_part
}
binary_connector_part = {
connector_end_member ~ to_token ~ connector_end_member
}
nary_connector_part = {
"(" ~ connector_end_member
~ "," ~ connector_end_member
~ ("," ~ connector_end_member)*
~ ")"
}
empty_source_end_member = { empty_source_end }
empty_source_end = { "" }
// Allocate keyword part - shared between allocation_usage and allocate_usage
// "allocate X to Y" or "allocate (X, Y, Z)"
allocate_keyword_part = {
allocate_token ~ allocate_part
}
// Allocate part - the "X to Y" or "(nary)" portion after allocate keyword
allocate_part = {
nary_allocate_part
| binary_allocate_part
}
binary_allocate_part = {
allocate_end_member ~ to_token ~ allocate_end_member
}
nary_allocate_part = {
"(" ~ allocate_end_member ~ "," ~ allocate_end_member ~ ("," ~ allocate_end_member)* ~ ")"
}
allocate_end_member = {
allocate_end
}
allocate_end = {
owned_cross_multiplicity_member? ~ allocate_end_reference
}
// Atomic rule matching qualified names with optional feature chains
// Matches: ActionTree::providePower.generateToAmplify
// or: Package::Type
// or: part.feature
// or: simple
allocate_qualified_feature_reference = @{
(identifier | quoted_name) ~ ("::" ~ (identifier | quoted_name) | "." ~ (identifier | quoted_name))*
}
// Match patterns like: ActionTree::providePower.generateToAmplify
// or: logical ::> l
// or: l.component
// or: simple
allocate_end_reference = {
identifier ~ references_operator ~ allocate_qualified_feature_reference
| quoted_name ~ references_operator ~ allocate_qualified_feature_reference
| allocate_qualified_feature_reference
| all_token
}
// Allocation usage with optional allocate part
// "allocation name : Type allocate X to Y;"
allocation_usage = {
occurrence_usage_prefix ~ allocation_token ~ usage_declaration? ~ allocate_keyword_part? ~ usage_body
}
// Allocate usage - shorthand form
// "allocate X to Y;"
allocate_usage = {
allocate_keyword_part ~ usage_body
}
// Messages
message_keyword = { message_token }
message = {
occurrence_usage_prefix ~ message_keyword ~ message_declaration ~ definition_body
}
message_declaration = {
message_event_member ~ to_token ~ message_event_member
| usage_declaration ~ value_part? ~ (of_token ~ payload_feature_member)? ~ (from_token ~ message_event_member ~ to_token ~ message_event_member)?
| value_part ~ (of_token ~ payload_feature_member)? ~ (from_token ~ message_event_member ~ to_token ~ message_event_member)?
| (of_token ~ payload_feature_member) ~ (from_token ~ message_event_member ~ to_token ~ message_event_member)?
| from_token ~ message_event_member ~ to_token ~ message_event_member
}
// Flow Members - PayloadFeature
payload_feature_member = {
payload_feature
}
payload_feature = {
payload
}
payload = {
identification? ~ payload_feature_specialization_part ~ value_part?
| identification? ~ value_part
| owned_feature_typing ~ owned_multiplicity?
| owned_multiplicity ~ owned_feature_typing
}
payload_feature_specialization_part = {
feature_specialization+ ~ multiplicity_part? ~ feature_specialization*
| multiplicity_part ~ feature_specialization+
}
message_event_member = {
message_event
}
message_event = {
owned_reference_subsetting
}
// Flow Members - FlowEnd
flow_end_member = {
flow_end
}
// FlowEnd: Either a feature chain (a.b.c) or a single feature reference
// The semantic layer will handle splitting the chain into subsetting + final feature
flow_end = {
owned_feature_chain
| flow_feature_member
}
flow_feature_member = {
flow_feature
}
flow_feature = {
flow_redefinition
}
flow_redefinition = {
feature_reference
}
flow_usage_keyword = { flow_keyword }
flow_usage = {
occurrence_usage_prefix ~ flow_usage_keyword ~ flow_usage_declaration ~ usage_body
}
// FlowConnectionUsageDeclaration per spec 8.2.2.9.5:
// ( UsageDeclaration? 'of'? FlowPart )?
// Where FlowPart = ('from' FlowEndMember)? 'to' FlowEndMember
//
// Ordering matters for PEG parsing:
// 1. of_token ~ owned_feature_typing ~ owned_multiplicity? ~ flow_part - handles "flow of Exposure[1] from X to Y" (typed with mult, no name)
// 2. flow_part - handles shorthand "flow X.Y to A.B" or "flow from X.Y to A.B" (no name)
// 3. usage_declaration ~ (of_token ~ owned_feature_typing ~ owned_multiplicity?)? ~ flow_part? - handles named "flow myFlow of Type[1] from X to Y"
// or "flow myFlow from X.Y to A.B"
flow_usage_declaration = {
of_token ~ owned_feature_typing ~ owned_multiplicity? ~ flow_part
| flow_part
| usage_declaration ~ (of_token ~ owned_feature_typing ~ owned_multiplicity?)? ~ flow_part?
}
// FlowPart supports both:
// - "from X to Y" (explicit source with from keyword)
// - "X to Y" (source without from keyword)
flow_part = {
from_token ~ flow_end_member ~ to_token ~ flow_end_member
| flow_end_member ~ to_token ~ flow_end_member
}
succession_flow_usage = {
succession_keyword ~ flow_usage_keyword ~ flow_usage_declaration ~ usage_body
}
// Action Usages
action_usage_keyword = { action_keyword }
action_usage = {
occurrence_usage_prefix ~ action_usage_keyword ~ action_usage_declaration ~ action_body
}
action_usage_declaration = {
usage_declaration? ~ function_parameter_list? ~ value_part?
}
perform_action_usage = {
occurrence_usage_prefix ~ perform_token ~ perform_action_usage_declaration ~ action_body
}
perform_action_usage_declaration = {
typed_reference ~ value_part?
| action_declaration_header ~ value_part?
}
// Calculation Usage
calculation_usage_keyword = { calculation_keyword }
calculation_usage = {
occurrence_usage_prefix ~ calculation_usage_keyword ~ action_usage_declaration ~ calculation_body
}
// State Usage
state_usage_keyword = { state_keyword }
state_usage = {
occurrence_usage_prefix ~ state_usage_keyword ~ action_usage_declaration ~ state_usage_body
}
state_usage_body = {
semi_colon
| parallel_marker? ~ forward_curl_brace ~ state_body_part ~ backward_curl_brace
}
// Constraint Keywords
constraint_keyword = { constraint_token }
constraint_def_keyword = { constraint_token ~ def_token }
// Constraint Definition
constraint_definition = {
occurrence_definition_prefix ~ constraint_def_keyword ~ definition_declaration ~ calculation_body
}
// Constraint Usage
constraint_usage_keyword = { constraint_keyword }
constraint_usage = {
occurrence_usage_prefix ~ constraint_usage_keyword ~ constraint_usage_declaration ~ calculation_body
}
// Concern Usage
concern_usage_keyword = { concern_token }
concern_usage = {
occurrence_usage_prefix ~ concern_usage_keyword ~ usage_declaration? ~ requirement_body
}
constraint_usage_declaration = {
usage_declaration? ~ value_part?
}
assert_constraint_usage = {
occurrence_usage_prefix ~ assert_token ~ not_token? ~ (
owned_reference_subsetting ~ feature_specialization_part?
| constraint_usage_keyword ~ constraint_usage_declaration?
) ~ constraint_body
}
constraint_body = {
";" | forward_curl_brace ~ constraint_body_part ~ backward_curl_brace
}
constraint_body_part = {
definition_body_item* ~ (visible_annotating_member* ~ owned_expression)?
}
// Requirement Usage
requirement_usage_keyword = { requirement_keyword }
requirement_usage = {
occurrence_usage_prefix ~ requirement_usage_keyword ~ constraint_usage_declaration ~ requirement_body
}
satisfy_requirement_usage = {
occurrence_usage_prefix ~ assert_token? ~ ("not")? ~ satisfy_token ~ (
requirement_usage_keyword ~ usage_declaration?
| owned_reference_subsetting ~ feature_specialization_part?
) ~ value_part? ~ ("by" ~ satisfaction_subject_member)? ~ requirement_body
}
satisfaction_subject_member = {
satisfaction_parameter
}
satisfaction_parameter = {
satisfaction_feature_value
}
satisfaction_feature_value = {
satisfaction_reference_expression
}
satisfaction_reference_expression = {
owned_feature_chain | qualified_name | feature_chain_member
}
// Case Usage Keywords
case_usage_keyword = { case_keyword }
// Case Usage
case_usage = {
occurrence_usage_prefix ~ case_usage_keyword ~ action_usage_declaration ~ case_body
}
// Analysis Case Usage
analysis_case_usage = {
occurrence_usage_prefix ~ analysis_keyword ~ action_usage_declaration ~ case_body
}
// Verification Case Usage
verification_case_usage = {
occurrence_usage_prefix ~ verification_keyword ~ action_usage_declaration ~ case_body
}
use_case_usage = {
occurrence_usage_prefix ~ use_token ~ case_token ~ usage_declaration? ~ case_body
}
// Viewpoint Usage
viewpoint_usage_keyword = { viewpoint_keyword }
viewpoint_usage = {
occurrence_usage_prefix ~ viewpoint_usage_keyword ~ constraint_usage_declaration ~ requirement_body
}
exhibit_state_usage = {
occurrence_usage_prefix ~ exhibit_token ~ (
state_usage_keyword ~ action_usage_declaration
| owned_reference_subsetting ~ feature_specialization_part? ~ value_part?
) ~ state_usage_body
}
// Transition Usage
transition_usage_keyword = { transition_token }
// TransitionUsage grammar:
// 'transition' UsageDeclaration? ('first' TransitionSourceMember | TransitionSourceMember) ...
// The 'first' keyword indicates this is not a self-loop.
// Order matters: try 'first' variant before bare source to avoid 'first' being consumed as identifier.
transition_usage = {
transition_usage_keyword
~ (
// Named transition with source: "transition name first source ..." or "transition name source ..."
usage_declaration ~ (first_token ~ transition_source_member | transition_source_member)
// Anonymous transition with source: "transition first source ..." or "transition source ..."
| first_token ~ transition_source_member
| transition_source_member
)
~ empty_parameter_member
~ (empty_parameter_member ~ trigger_action_member)?
~ guard_expression_member?
~ effect_behavior_member?
~ then_token ~ transition_succession_member
~ action_body
}
target_transition_usage = {
empty_parameter_member
~ (transition_usage_keyword
~ (empty_parameter_member ~ trigger_action_member)?
~ guard_expression_member?
~ effect_behavior_member?
| empty_parameter_member ~ trigger_action_member
~ guard_expression_member?
~ effect_behavior_member?
| guard_expression_member
~ effect_behavior_member?
)?
~ then_token ~ transition_succession_member
~ action_body
}
transition_source_member = {
owned_feature_chain
| feature_reference
}
trigger_action_member = {
trigger_feature_kind ~ trigger_action
}
trigger_feature_kind = { accept_token }
trigger_action = {
accept_parameter_part
}
guard_expression_member = {
guard_feature_kind ~ owned_expression
}
guard_feature_kind = { "if" }
effect_behavior_member = {
effect_feature_kind ~ effect_behavior_usage
}
effect_feature_kind = { do_token }
effect_behavior_usage = {
performed_action_usage ~ (forward_curl_brace ~ action_body_item* ~ backward_curl_brace)?
| empty_action_usage
}
transition_succession_member = {
transition_succession
}
transition_succession = {
empty_source_end_member ~ connector_end_member
}
include_use_case_usage = {
include_token ~ (use_token ~ case_token)? ~ (owned_feature_chain | usage_declaration) ~ case_body
}
// Classifiers (reusing KerML rules with same names for compatibility)
// Note: specializes_token and other feature relationship tokens are defined
// in the "Tokens for feature relationships" section below
subclassification_part = {
specializes_operator
~ owned_subclassification
~ ("," ~ owned_subclassification)*
}
redefinition_part = {
redefines_operator
~ owned_subclassification
~ ("," ~ owned_subclassification)*
}
owned_subclassification = { classifier_reference }
classifier_reference = { qualified_name | identifier | quoted_name }
// Features
feature_declaration = {
identification ~ feature_specialization_part?
| feature_specialization_part
}
feature_specialization_part = {
feature_specialization+ ~ multiplicity_part ~ feature_specialization*
| feature_specialization+
| multiplicity_part ~ feature_specialization*
| multiplicity_part
}
multiplicity_part = {
owned_multiplicity ~ multiplicity_properties?
| multiplicity_properties
}
feature_specialization = {
typings
| subsettings
| references
| crosses
| redefinitions
}
// Feature relationship patterns
typings = { typed_by ~ ("," ~ feature_typing)* }
typed_by = { typed_by_token ~ feature_typing }
subsettings = { subsets ~ ("," ~ owned_subsetting)* }
subsets = { subsets_operator ~ owned_subsetting }
references = { references_operator ~ owned_reference_subsetting }
crosses = { crosses_operator ~ owned_cross_subsetting }
redefinitions = { redefines ~ ("," ~ owned_redefinition)* }
redefines = { redefines_operator ~ owned_redefinition }
// Feature typing, subsetting, and redefinition
feature_typing = {
owned_feature_typing
| conjugated_port_typing
}
// OwnedFeatureTyping - supports optional ~ prefix for conjugated port types
owned_feature_typing = { conjugation_operator? ~ feature_reference }
// Feature subsetting and redefinition rules
owned_subsetting = {
owned_feature_chain
| feature_reference
}
owned_reference_subsetting = {
owned_feature_chain
| feature_reference
}
owned_cross_subsetting = {
owned_feature_chain
| feature_reference
}
owned_redefinition = {
owned_feature_chain
| feature_reference
}
// Feature references and chains (matching KerML structure)
feature_reference = { qualified_name | identifier | quoted_name | all_token}
// Use @{ } (atomic) to prevent trailing whitespace from being included in span
owned_feature_chain = @{ (identifier | quoted_name) ~ ("." ~ (identifier | quoted_name))+ }
// Multiplicity (matching KerML structure)
owned_multiplicity = { "[" ~ multiplicity_range ~ "]" }
multiplicity_range = {
lower_bound ~ ".." ~ upper_bound
| bound
}
lower_bound = { owned_expression | "*" }
upper_bound = { owned_expression | "*" }
bound = { owned_expression | "*" }
number_literal = @{ ASCII_DIGIT+ }
multiplicity_properties = {
ordered_token ~ nonunique_token
| nonunique_token ~ ordered_token
| ordered_token
| nonunique_token
}
// Model Entry Point
// RootNamespace is the semantic entry point per the official SysML v2 grammar
// It represents an implicit root namespace containing all top-level elements
root_namespace = { package_body_element* }
// Package body elements that can appear at the root level
package_body_element = {
package
| library_package
| import
| alias_member_element
| element_filter_member
| visible_annotating_member
| usage_member
| definition_member_element
| relationship_member_element
| dependency
}
// Legacy namespace_element alias for compatibility
namespace_element = { package_body_element }
// Supporting Rules
element_reference = { qualified_name | identifier | quoted_name }
short_name = { "<" ~ (identifier | quoted_name) ~ ">" }
regular_name = { identifier | quoted_name }
identification = { (short_name ~ regular_name?) | regular_name }
quoted_name = @{ "'" ~ (!("'") ~ ANY)+ ~ "'" }
relationship_body = { ";" | ( forward_curl_brace ~ relationship_body_elements ~ backward_curl_brace ) }
relationship_body_elements = { owned_annotation* }
// Metadata annotation names can be any word including keywords (e.g., #original, #derive, #derivation)
metadata_annotation_name = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* }
prefix_metadata_annotation = { "#" ~ metadata_annotation_name }
// Annotations
owned_annotation = { annotating_element }
annotating_member = { annotating_element }
annotating_element = {
comment_annotation
| documentation
| textual_representation
| metadata_usage_annotation
| locale_annotation
| ignored_block_comment
}
ignored_block_comment = _{ block_comment }
locale_annotation = { locale_token ~ string_value ~ block_comment? }
comment_annotation = { comment_token ~ identifier? ~ (locale_token ~ quoted_name)? ~ (about_token ~ element_reference ~ ("," ~ element_reference)*)? ~ (block_comment | semi_colon)? }
documentation = { doc_token ~ identifier? ~ (locale_token ~ quoted_name)? ~ (block_comment | semi_colon)? }
textual_representation = {
rep_token ~ textual_rep_name? ~ language_token ~ string_value ~ block_comment?
| language_token ~ string_value ~ block_comment?
}
textual_rep_name = { !language_token ~ identifier }
metadata_usage_annotation = { "#" ~ metadata_annotation_name ~ semi_colon }
// Metadata
metadata_definition = {
abstract_token?
~ prefix_metadata?
~ metadata_token
~ def_token
~ short_name?
~ definition_suffix
}
prefix_metadata_annotation_element = { prefix_metadata_usage }
prefix_metadata_member = { prefix_metadata_usage }
prefix_metadata = { prefix_metadata_member+ }
prefix_metadata_usage = { "#" ~ metadata_typing }
// State-related placeholder rules
metadata_typing = { identifier | "meta" }
metadata_usage = {
prefix_metadata?
~ (metadata_token | at_symbol)
~ metadata_usage_declaration
~ (about_token ~ annotation ~ ("," ~ annotation)*)?
~ metadata_body
}
metadata_usage_declaration = {
(identification? ~ defined_by_token)? ~ metadata_typing
}
annotation = { qualified_name | identifier }
metadata_body = { ";" | ( forward_curl_brace ~ metadata_body_items ~ backward_curl_brace ) }
metadata_body_items = {
(definition_member
| relationship_member
| visible_annotating_member
| metadata_body_usage_member
| metadata_alias_member
| import)*
}
metadata_body_usage_member = { metadata_body_usage }
// MetadataBodyUsage follows spec: 'ref'? (':>>' | 'redefines')? OwnedRedefinition FeatureSpecializationPart? ValuePart? MetadataBody
// OwnedRedefinition is a required identifier (the feature being redefined)
metadata_body_usage = {
ref_token?
~ redefines_operator?
~ identifier
~ feature_specialization_part?
~ value_part?
~ metadata_body
}
relationship_member = { identifier ~ semi_colon }
visible_annotating_member = { annotating_element }
metadata_alias_member = { alias_token ~ identifier ~ for_token ~ identifier ~ semi_colon }
// Imports - per official SysML v2 grammar
// Import is either a MembershipImport or NamespaceImport
import_prefix = { visibility? ~ import_token ~ import_all? }
import_all = { all_token }
// Use @{ } (atomic) to prevent trailing whitespace from being included in span
qualified_name = @{ (identifier | quoted_name) ~ ("::" ~ (identifier | quoted_name))* }
namespace_marker = { "::*" }
recursive_marker = { "::**" }
// MembershipImport: imports a specific member by qualified name
// e.g., "import MyPackage::MyElement" or "import MyPackage::MyElement::**"
imported_membership = {
qualified_name ~ recursive_marker?
}
// NamespaceImport: imports all members of a namespace
// e.g., "import MyPackage::*" or "import MyPackage::*::**"
// Uses negative lookahead to prevent namespace_marker from matching start of recursive_marker
imported_namespace = {
qualified_name ~ !recursive_marker ~ namespace_marker ~ recursive_marker?
}
// MembershipImport production
membership_import = {
import_prefix ~ imported_membership
}
// NamespaceImport production
namespace_import = {
import_prefix ~ imported_namespace
}
// Main import rule - union of membership and namespace imports
// IMPORTANT: namespace_import must come first since it's more specific
// (membership_import would partially match namespace patterns)
// filter_package? is optional and applies to both import types
import = {
(namespace_import | membership_import)
~ filter_package?
~ relationship_body
}
// FilterPackage: optional filter expressions for imports
// e.g., "import X::*[filter1][filter2]"
filter_package = { filter_package_member+ }
filter_package_member = { "[" ~ owned_expression ~ "]" }
// Dependency
dependency = {
prefix_metadata?
~ dependency_token
~ ((identification ~ from_token) | from_token)?
~ element_reference ~ ("," ~ element_reference)*
~ to_token
~ element_reference ~ ("," ~ element_reference)*
~ relationship_body
}
// Entry point - uses root_namespace for semantic model
file = { SOI ~ root_namespace ~ EOI }