use super::*;
pub fn parse_bind_usage<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::BINDING_CONNECTOR);
p.expect(SyntaxKind::BIND_KW);
p.skip_trivia();
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
if p.at(SyntaxKind::EQ) {
p.bump();
p.skip_trivia();
}
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
p.parse_body();
p.finish_node();
}
pub fn parse_assign_action<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::USAGE);
p.expect(SyntaxKind::ASSIGN_KW);
p.skip_trivia();
if p.at_name_token() {
p.parse_qualified_name(); p.skip_trivia();
}
if p.at(SyntaxKind::COLON_EQ) {
p.bump();
p.skip_trivia();
parse_expression(p);
p.skip_trivia();
}
p.parse_body();
p.finish_node();
}
pub fn parse_connect_usage<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::CONNECT_USAGE);
p.expect(SyntaxKind::CONNECT_KW);
p.skip_trivia();
if p.at(SyntaxKind::L_PAREN) {
p.start_node(SyntaxKind::CONNECTOR_PART);
p.bump(); p.skip_trivia();
parse_connector_end(p);
p.skip_trivia();
while p.at(SyntaxKind::COMMA) {
p.bump();
p.skip_trivia();
parse_connector_end(p);
p.skip_trivia();
}
p.expect(SyntaxKind::R_PAREN);
p.finish_node(); p.skip_trivia();
} else {
p.start_node(SyntaxKind::CONNECTOR_PART);
parse_connector_end(p);
p.skip_trivia();
if p.at(SyntaxKind::TO_KW) {
p.bump();
p.skip_trivia();
parse_connector_end(p);
p.skip_trivia();
}
p.finish_node(); }
p.parse_body();
p.finish_node();
}
pub fn parse_connector_end<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::CONNECTOR_END);
parse_optional_multiplicity(p);
parse_connector_end_reference(p);
p.finish_node();
}
fn parse_connector_end_reference<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::CONNECTOR_END_REFERENCE);
if p.at_name_token() {
parse_qualified_name_and_skip(p);
if p.at(SyntaxKind::COLON_COLON_GT) || p.at(SyntaxKind::REFERENCES_KW) {
bump_keyword(p);
parse_qualified_name_and_skip(p);
}
}
p.finish_node();
}
pub fn parse_connector_usage<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::CONNECTOR);
expect_and_skip(p, SyntaxKind::CONNECTOR_KW);
parse_optional_identification(p);
parse_optional_typing(p);
parse_specializations_with_skip(p);
if p.at(SyntaxKind::FROM_KW) {
bump_keyword(p);
parse_optional_qualified_name(p);
if p.at(SyntaxKind::TO_KW) {
bump_keyword(p);
parse_optional_qualified_name(p);
}
}
p.parse_body();
p.finish_node();
}
pub fn parse_binding_or_succession<P: SysMLParser>(p: &mut P) {
let is_succession = p.at(SyntaxKind::SUCCESSION_KW);
if is_succession && p.peek_kind(1) == SyntaxKind::FLOW_KW {
parse_flow_usage(p);
return;
}
if is_succession {
p.start_node(SyntaxKind::SUCCESSION);
} else {
p.start_node(SyntaxKind::BINDING_CONNECTOR);
}
p.bump(); p.skip_trivia();
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
if !is_succession && p.at(SyntaxKind::BIND_KW) {
p.bump(); p.skip_trivia();
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
if p.at(SyntaxKind::EQ) {
p.bump();
p.skip_trivia();
}
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
p.parse_body();
p.finish_node();
return;
}
let mut parsed_name = false;
if p.at(SyntaxKind::REDEFINES_KW) || p.at(SyntaxKind::COLON_GT_GT) {
p.bump();
p.skip_trivia();
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
parsed_name = true;
}
} else if p.at_name_token() && !p.at(SyntaxKind::FIRST_KW) && !p.at(SyntaxKind::BIND_KW) {
let is_binding_source = !is_succession && peek_past_name_for(p, SyntaxKind::EQ);
let is_succession_source = is_succession && peek_past_name_for(p, SyntaxKind::THEN_KW);
if !is_binding_source && !is_succession_source {
p.parse_identification();
p.skip_trivia();
parsed_name = true;
}
}
if !is_succession && p.at(SyntaxKind::BIND_KW) {
p.bump(); p.skip_trivia();
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
if p.at(SyntaxKind::EQ) {
p.bump();
p.skip_trivia();
}
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
p.parse_body();
p.finish_node();
return;
}
if !is_succession && p.at(SyntaxKind::OF_KW) {
p.bump();
p.skip_trivia();
}
if is_succession && p.at(SyntaxKind::COLON) {
p.parse_typing();
p.skip_trivia();
}
if is_succession && p.at(SyntaxKind::FIRST_KW) {
p.bump(); p.skip_trivia();
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
if p.at(SyntaxKind::THEN_KW) {
p.bump(); p.skip_trivia();
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
} else if p.at(SyntaxKind::IF_KW) {
p.bump(); p.skip_trivia();
if p.can_start_expression() {
parse_expression(p);
p.skip_trivia();
}
if p.at(SyntaxKind::THEN_KW) {
p.bump();
p.skip_trivia();
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
}
} else if p.at(SyntaxKind::ELSE_KW) {
p.bump(); p.skip_trivia();
if p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
}
} else {
if !parsed_name && p.at_name_token() {
p.parse_qualified_name();
p.skip_trivia();
}
if p.at(SyntaxKind::EQ) || p.at(SyntaxKind::THEN_KW) {
p.bump();
p.skip_trivia();
if p.at_name_token() {
p.parse_qualified_name();
}
}
}
p.skip_trivia();
p.parse_body();
p.finish_node();
}
pub fn parse_flow_usage<P: SysMLParser>(p: &mut P) {
p.start_node(SyntaxKind::USAGE);
if p.at(SyntaxKind::ABSTRACT_KW) {
p.bump();
p.skip_trivia();
}
if p.at(SyntaxKind::SUCCESSION_KW) {
p.bump();
p.skip_trivia();
}
p.expect(SyntaxKind::FLOW_KW);
p.skip_trivia();
if p.at(SyntaxKind::ALL_KW) {
p.bump();
p.skip_trivia();
}
let is_direct_flow = peek_for_direct_flow(p);
let has_of_clause = p.at(SyntaxKind::OF_KW);
if is_direct_flow {
p.parse_qualified_name();
p.skip_trivia();
if p.at(SyntaxKind::TO_KW) {
p.bump();
p.skip_trivia();
p.parse_qualified_name();
}
} else if has_of_clause {
p.bump(); p.skip_trivia();
p.parse_qualified_name(); p.skip_trivia();
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
parse_optional_from_to(p);
} else {
if (p.at_name_token() || p.at(SyntaxKind::LT)) && !p.at(SyntaxKind::FROM_KW) {
p.parse_identification();
p.skip_trivia();
}
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
if p.at(SyntaxKind::COLON) {
p.parse_typing();
p.skip_trivia();
}
parse_specializations(p);
p.skip_trivia();
if p.at(SyntaxKind::EQ) || p.at(SyntaxKind::COLON_EQ) {
p.bump();
p.skip_trivia();
parse_expression(p);
p.skip_trivia();
}
if p.at(SyntaxKind::OF_KW) {
p.bump();
p.skip_trivia();
p.parse_qualified_name();
p.skip_trivia();
if p.at(SyntaxKind::L_BRACKET) {
p.parse_multiplicity();
p.skip_trivia();
}
}
parse_optional_from_to(p);
}
p.skip_trivia();
p.parse_body();
p.finish_node();
}
fn peek_for_direct_flow<P: SysMLParser>(p: &P) -> bool {
if p.current_kind() == SyntaxKind::FROM_KW {
return false;
}
if p.peek_kind(1) == SyntaxKind::COLON {
return false;
}
let mut saw_from = false;
for i in 1..9 {
let kind = p.peek_kind(i);
if kind == SyntaxKind::FROM_KW {
saw_from = true;
}
if kind == SyntaxKind::TO_KW {
if saw_from {
return false;
}
return true;
}
if matches!(
kind,
SyntaxKind::COLON
| SyntaxKind::EQ
| SyntaxKind::COLON_EQ
| SyntaxKind::COLON_GT
| SyntaxKind::COLON_GT_GT
| SyntaxKind::SPECIALIZES_KW
) {
return false;
}
if matches!(
kind,
SyntaxKind::SEMICOLON | SyntaxKind::L_BRACE | SyntaxKind::ERROR
) {
return false;
}
}
false
}