feat(parser): make header & paragraph parsing indent-sensitive
parent
80a96a3e33
commit
82d5aa6078
|
@ -13,6 +13,8 @@
|
||||||
struct mrk_parser {
|
struct mrk_parser {
|
||||||
mrk_lexer *lexer;
|
mrk_lexer *lexer;
|
||||||
mrk_token next_token;
|
mrk_token next_token;
|
||||||
|
// Indentation of the current line
|
||||||
|
size_t indent;
|
||||||
struct {
|
struct {
|
||||||
mrk_token token;
|
mrk_token token;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
|
@ -43,7 +45,10 @@ void mrk_parser_advance(mrk_parser *parser);
|
||||||
*/
|
*/
|
||||||
mrk_err mrk_parser_eat(mrk_token *out, mrk_parser *parser, mrk_token_type type);
|
mrk_err mrk_parser_eat(mrk_token *out, mrk_parser *parser, mrk_token_type type);
|
||||||
|
|
||||||
mrk_err mrk_parser_parse_block(mrk_ast_node *out, mrk_parser *parser);
|
/**
|
||||||
|
* Consume all following ident tokens and store how many were seen
|
||||||
|
*/
|
||||||
|
void mrk_parser_indent(mrk_parser *parser);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse an entire header block.
|
* Parse an entire header block.
|
||||||
|
|
|
@ -19,6 +19,8 @@ mrk_err mrk_parser_parse(mrk_ast_node **out, mrk_parser *parser) {
|
||||||
MRK_RES(mrk_ast_node_init(&root));
|
MRK_RES(mrk_ast_node_init(&root));
|
||||||
|
|
||||||
while (!mrk_parser_done(parser)) {
|
while (!mrk_parser_done(parser)) {
|
||||||
|
mrk_parser_indent(parser);
|
||||||
|
|
||||||
mrk_ast_node *child;
|
mrk_ast_node *child;
|
||||||
MRK_RES(mrk_ast_node_child_append(&child, root));
|
MRK_RES(mrk_ast_node_child_append(&child, root));
|
||||||
|
|
||||||
|
@ -45,8 +47,10 @@ mrk_err mrk_parser_parse_header(mrk_ast_node *out, mrk_parser *parser) {
|
||||||
out->type = mrk_ast_node_type_header;
|
out->type = mrk_ast_node_type_header;
|
||||||
out->d.header.depth = mrk_token_len(header_token);
|
out->d.header.depth = mrk_token_len(header_token);
|
||||||
|
|
||||||
|
size_t header_indent = parser->indent;
|
||||||
|
|
||||||
// Parse subsections of header
|
// Parse subsections of header
|
||||||
while (!mrk_parser_done(parser)) {
|
while (!mrk_parser_done(parser) && parser->indent == header_indent) {
|
||||||
mrk_ast_node *child;
|
mrk_ast_node *child;
|
||||||
|
|
||||||
switch (mrk_parser_peek(parser).type) {
|
switch (mrk_parser_peek(parser).type) {
|
||||||
|
@ -59,6 +63,7 @@ mrk_err mrk_parser_parse_header(mrk_ast_node *out, mrk_parser *parser) {
|
||||||
MRK_RES(mrk_ast_node_child_append(&child, out));
|
MRK_RES(mrk_ast_node_child_append(&child, out));
|
||||||
child->type = mrk_ast_node_type_space;
|
child->type = mrk_ast_node_type_space;
|
||||||
mrk_parser_advance(parser);
|
mrk_parser_advance(parser);
|
||||||
|
mrk_parser_indent(parser);
|
||||||
break;
|
break;
|
||||||
case mrk_token_type_left_bracket:
|
case mrk_token_type_left_bracket:
|
||||||
MRK_RES(mrk_ast_node_child_append(&child, out));
|
MRK_RES(mrk_ast_node_child_append(&child, out));
|
||||||
|
@ -67,6 +72,7 @@ mrk_err mrk_parser_parse_header(mrk_ast_node *out, mrk_parser *parser) {
|
||||||
// Header definition ends at newline
|
// Header definition ends at newline
|
||||||
case mrk_token_type_blank_line:
|
case mrk_token_type_blank_line:
|
||||||
mrk_parser_advance(parser);
|
mrk_parser_advance(parser);
|
||||||
|
mrk_parser_indent(parser);
|
||||||
return mrk_err_ok;
|
return mrk_err_ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +132,9 @@ mrk_err mrk_parser_parse_link(mrk_ast_node *out, mrk_parser *parser) {
|
||||||
mrk_err mrk_parser_parse_paragraph(mrk_ast_node *out, mrk_parser *parser) {
|
mrk_err mrk_parser_parse_paragraph(mrk_ast_node *out, mrk_parser *parser) {
|
||||||
out->type = mrk_ast_node_type_paragraph;
|
out->type = mrk_ast_node_type_paragraph;
|
||||||
|
|
||||||
while (!mrk_parser_done(parser)) {
|
size_t indent = parser->indent;
|
||||||
|
|
||||||
|
while (!mrk_parser_done(parser) && parser->indent == indent) {
|
||||||
mrk_ast_node *child;
|
mrk_ast_node *child;
|
||||||
|
|
||||||
switch (mrk_parser_peek(parser).type) {
|
switch (mrk_parser_peek(parser).type) {
|
||||||
|
@ -142,12 +150,18 @@ mrk_err mrk_parser_parse_paragraph(mrk_ast_node *out, mrk_parser *parser) {
|
||||||
MRK_RES(mrk_ast_node_child_append(&child, out));
|
MRK_RES(mrk_ast_node_child_append(&child, out));
|
||||||
child->type = mrk_ast_node_type_space;
|
child->type = mrk_ast_node_type_space;
|
||||||
mrk_parser_advance(parser);
|
mrk_parser_advance(parser);
|
||||||
|
mrk_parser_indent(parser);
|
||||||
break;
|
break;
|
||||||
case mrk_token_type_blank_line:
|
case mrk_token_type_blank_line:
|
||||||
mrk_parser_advance(parser);
|
mrk_parser_advance(parser);
|
||||||
|
mrk_parser_indent(parser);
|
||||||
return mrk_err_ok;
|
return mrk_err_ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mrk_err_ok;
|
return mrk_err_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mrk_err mrk_parser_parse_list(mrk_ast_node *out, mrk_parser *parser) {
|
||||||
|
return mrk_err_invalid;
|
||||||
|
}
|
||||||
|
|
|
@ -36,3 +36,15 @@ mrk_err mrk_parser_eat(mrk_token *out, mrk_parser *parser,
|
||||||
|
|
||||||
return mrk_err_ok;
|
return mrk_err_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mrk_parser_indent(mrk_parser *parser) {
|
||||||
|
size_t seen = 0;
|
||||||
|
|
||||||
|
while (!mrk_parser_done(parser) &&
|
||||||
|
mrk_parser_peek(parser).type == mrk_token_type_indent) {
|
||||||
|
mrk_parser_advance(parser);
|
||||||
|
seen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser->indent = seen;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue