Skip to content

Commit

Permalink
child blocks come at the end of a node
Browse files Browse the repository at this point in the history
but there can be multiple iff all but one are slashdashed
  • Loading branch information
tjol committed Dec 7, 2024
1 parent ab8b702 commit 2a4f8d7
Showing 1 changed file with 31 additions and 6 deletions.
37 changes: 31 additions & 6 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ enum _kdl_parser_state {
PARSER_FLAG_MAYBE_IN_PROPERTY = 0x2000,
PARSER_FLAG_BARE_PROPERTY_NAME = 0x4000,
PARSER_FLAG_NEWLINES_ARE_WHITESPACE = 0x8000,
PARSER_FLAG_END_OF_NODE = 0x10000,
PARSER_FLAG_END_OF_NODE_OR_CHILD_BLOCK = 0x20000,
PARSER_FLAG_CONTEXTUALLY_ILLEGAL_WHITESPACE = 0x100000,
// Bitmask for testing the state
PARSER_MASK_WHITESPACE_CONTEXTUALLY_BANNED = //
Expand Down Expand Up @@ -409,6 +411,9 @@ static kdl_event_data* _next_node(kdl_parser* self, kdl_token* token)
if (self->slashdash_depth == self->depth + 1) {
// slashdash is ending here
self->slashdash_depth = -1;
self->state |= PARSER_FLAG_END_OF_NODE_OR_CHILD_BLOCK;
} else {
self->state |= PARSER_FLAG_END_OF_NODE;
}
return NULL;
}
Expand Down Expand Up @@ -528,6 +533,7 @@ static kdl_event_data* _next_event_in_node(kdl_parser* self, kdl_token* token)
return &self->event;
}
} else {
// End of node cases: always valid
switch (token->type) {
case KDL_TOKEN_END_CHILDREN:
// end this node, and process the token again
Expand All @@ -548,6 +554,31 @@ static kdl_event_data* _next_event_in_node(kdl_parser* self, kdl_token* token)
ev = _apply_slashdash(self);
return ev;
}
default:
break;
}

// Child block: valid unless we've had a non-slashdashed child block
// already or slashdash is active now
if (self->state & PARSER_FLAG_END_OF_NODE && self->slashdash_depth < 0) {
_set_parse_error(self, "Expected end of node");
return &self->event;
}
if (token->type == KDL_TOKEN_START_CHILDREN) {
// Next event will probably be a new node
self->state = PARSER_OUTSIDE_NODE;
++self->depth;
_reset_event(self);
return NULL;
}

// Args, props: only valid at the start
if (self->state & (PARSER_FLAG_END_OF_NODE | PARSER_FLAG_END_OF_NODE_OR_CHILD_BLOCK)) {
_set_parse_error(self, "Expected end of node or child block");
return &self->event;
}

switch (token->type) {
case KDL_TOKEN_WORD:
case KDL_TOKEN_STRING:
case KDL_TOKEN_MULTILINE_STRING:
Expand Down Expand Up @@ -615,12 +646,6 @@ static kdl_event_data* _next_event_in_node(kdl_parser* self, kdl_token* token)
self->state |= PARSER_FLAG_TYPE_ANNOTATION_START;
return NULL;
}
case KDL_TOKEN_START_CHILDREN:
// enter the node / allow new children
self->state = PARSER_OUTSIDE_NODE;
++self->depth;
_reset_event(self);
return NULL;
default:
_set_parse_error(self, "Unexpected token");
return &self->event;
Expand Down

0 comments on commit 2a4f8d7

Please sign in to comment.