2024-03-07 14:57:01 +01:00
|
|
|
#include "mrk/parser_internal.h"
|
2024-03-15 22:24:19 +01:00
|
|
|
#include <stdio.h>
|
2024-03-07 14:57:01 +01:00
|
|
|
|
2024-03-12 20:51:48 +01:00
|
|
|
mrk_err mrk_parser_init(mrk_parser **out) {
|
|
|
|
MRK_CALLOC(out, 1, sizeof(mrk_parser));
|
|
|
|
|
|
|
|
return mrk_err_ok;
|
|
|
|
}
|
|
|
|
|
2024-03-07 14:57:01 +01:00
|
|
|
void mrk_parser_open(mrk_parser *parser, mrk_lexer *lexer) {
|
|
|
|
parser->lexer = lexer;
|
|
|
|
|
2024-03-15 22:24:19 +01:00
|
|
|
// Prefill lookahead character
|
|
|
|
mrk_parser_advance(parser);
|
2024-03-07 14:57:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
mrk_err mrk_parser_parse(mrk_ast_node **out, mrk_parser *parser) {
|
|
|
|
mrk_ast_node *root;
|
|
|
|
MRK_RES(mrk_ast_node_init(&root));
|
|
|
|
|
2024-03-12 20:51:48 +01:00
|
|
|
while (!mrk_parser_done(parser)) {
|
2024-03-11 12:31:25 +01:00
|
|
|
mrk_ast_node *child;
|
|
|
|
MRK_RES(mrk_ast_node_child_append(&child, root));
|
2024-03-07 14:57:01 +01:00
|
|
|
|
2024-03-15 21:59:34 +01:00
|
|
|
switch (mrk_parser_peek(parser).type) {
|
|
|
|
case mrk_token_type_header_start:
|
|
|
|
MRK_RES(mrk_parser_parse_header(child, parser));
|
|
|
|
break;
|
2024-03-15 22:24:19 +01:00
|
|
|
case mrk_token_type_text:
|
|
|
|
case mrk_token_type_left_bracket:
|
|
|
|
MRK_RES(mrk_parser_parse_paragraph(child, parser));
|
|
|
|
break;
|
2024-03-15 21:59:34 +01:00
|
|
|
}
|
2024-03-11 12:31:25 +01:00
|
|
|
}
|
2024-03-10 21:29:37 +01:00
|
|
|
|
2024-03-15 21:59:34 +01:00
|
|
|
*out = root;
|
2024-03-10 21:29:37 +01:00
|
|
|
|
2024-03-11 12:31:25 +01:00
|
|
|
return mrk_err_ok;
|
2024-03-10 21:29:37 +01:00
|
|
|
}
|
|
|
|
|
2024-03-11 12:31:25 +01:00
|
|
|
mrk_err mrk_parser_parse_header(mrk_ast_node *out, mrk_parser *parser) {
|
|
|
|
mrk_token header_token;
|
|
|
|
mrk_parser_eat(&header_token, parser, mrk_token_type_header_start);
|
|
|
|
|
|
|
|
out->type = mrk_ast_node_type_header;
|
2024-03-15 21:59:34 +01:00
|
|
|
out->d.header.depth = mrk_token_len(header_token);
|
2024-03-11 12:31:25 +01:00
|
|
|
|
|
|
|
// Parse subsections of header
|
2024-03-15 21:59:34 +01:00
|
|
|
while (!mrk_parser_done(parser)) {
|
2024-03-11 12:31:25 +01:00
|
|
|
mrk_ast_node *child;
|
|
|
|
|
|
|
|
switch (mrk_parser_peek(parser).type) {
|
|
|
|
case mrk_token_type_text:
|
2024-03-15 21:59:34 +01:00
|
|
|
MRK_RES(mrk_ast_node_child_append(&child, out));
|
2024-03-11 12:31:25 +01:00
|
|
|
MRK_RES(mrk_parser_parse_text(child, parser));
|
|
|
|
break;
|
|
|
|
// Newlines are interpreted as spaces
|
|
|
|
case mrk_token_type_newline:
|
2024-03-15 21:59:34 +01:00
|
|
|
MRK_RES(mrk_ast_node_child_append(&child, out));
|
2024-03-11 12:31:25 +01:00
|
|
|
child->type = mrk_ast_node_type_space;
|
|
|
|
mrk_parser_advance(parser);
|
|
|
|
break;
|
2024-03-12 20:51:48 +01:00
|
|
|
case mrk_token_type_left_bracket:
|
2024-03-15 21:59:34 +01:00
|
|
|
MRK_RES(mrk_ast_node_child_append(&child, out));
|
|
|
|
MRK_RES(mrk_parser_parse_link(child, parser));
|
2024-03-12 20:51:48 +01:00
|
|
|
break;
|
2024-03-15 21:59:34 +01:00
|
|
|
// Header definition ends at newline
|
|
|
|
case mrk_token_type_blank_line:
|
|
|
|
mrk_parser_advance(parser);
|
|
|
|
return mrk_err_ok;
|
2024-03-11 12:31:25 +01:00
|
|
|
}
|
2024-03-10 21:29:37 +01:00
|
|
|
}
|
|
|
|
|
2024-03-11 12:31:25 +01:00
|
|
|
return mrk_err_ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
mrk_err mrk_parser_parse_text(mrk_ast_node *out, mrk_parser *parser) {
|
|
|
|
mrk_token text_token;
|
|
|
|
MRK_RES(mrk_parser_eat(&text_token, parser, mrk_token_type_text));
|
|
|
|
|
2024-03-12 20:51:48 +01:00
|
|
|
out->type = mrk_ast_node_type_text;
|
2024-03-15 21:59:34 +01:00
|
|
|
out->d.text.start = text_token.start;
|
|
|
|
out->d.text.end = text_token.end;
|
2024-03-11 12:31:25 +01:00
|
|
|
|
2024-03-10 21:29:37 +01:00
|
|
|
return mrk_err_ok;
|
|
|
|
}
|
2024-03-12 20:51:48 +01:00
|
|
|
|
|
|
|
mrk_err mrk_parser_parse_link(mrk_ast_node *out, mrk_parser *parser) {
|
2024-03-15 21:59:34 +01:00
|
|
|
out->type = mrk_ast_node_type_link;
|
|
|
|
|
2024-03-12 20:51:48 +01:00
|
|
|
MRK_RES(mrk_parser_eat(NULL, parser, mrk_token_type_left_bracket));
|
2024-03-15 21:59:34 +01:00
|
|
|
|
|
|
|
if (mrk_parser_done(parser)) {
|
|
|
|
parser->error.msg = "Unclosed brackets";
|
|
|
|
return mrk_err_invalid;
|
|
|
|
}
|
|
|
|
|
|
|
|
mrk_ast_node *child;
|
|
|
|
MRK_RES(mrk_ast_node_child_append(&child, out));
|
|
|
|
|
|
|
|
switch (mrk_parser_peek(parser).type) {
|
|
|
|
case mrk_token_type_text:
|
|
|
|
MRK_RES(mrk_parser_parse_text(child, parser));
|
|
|
|
break;
|
|
|
|
// TODO allow other types of text (e.g. cursive)
|
|
|
|
// TODO image links
|
|
|
|
default:
|
|
|
|
// TODO throw error
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
MRK_RES(mrk_parser_eat(NULL, parser, mrk_token_type_right_bracket));
|
|
|
|
MRK_RES(mrk_parser_eat(NULL, parser, mrk_token_type_left_paren));
|
|
|
|
|
|
|
|
mrk_token url_token;
|
|
|
|
MRK_RES(mrk_parser_eat(&url_token, parser, mrk_token_type_text));
|
|
|
|
|
|
|
|
MRK_RES(mrk_parser_eat(NULL, parser, mrk_token_type_right_paren));
|
|
|
|
|
|
|
|
out->d.link.url_start = url_token.start;
|
|
|
|
out->d.link.url_end = url_token.end;
|
|
|
|
|
|
|
|
return mrk_err_ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
mrk_err mrk_parser_parse_paragraph(mrk_ast_node *out, mrk_parser *parser) {
|
|
|
|
out->type = mrk_ast_node_type_paragraph;
|
|
|
|
|
|
|
|
while (!mrk_parser_done(parser)) {
|
|
|
|
mrk_ast_node *child;
|
|
|
|
|
|
|
|
switch (mrk_parser_peek(parser).type) {
|
|
|
|
case mrk_token_type_text:
|
|
|
|
MRK_RES(mrk_ast_node_child_append(&child, out));
|
|
|
|
MRK_RES(mrk_parser_parse_text(child, parser));
|
|
|
|
break;
|
|
|
|
case mrk_token_type_left_bracket:
|
|
|
|
MRK_RES(mrk_ast_node_child_append(&child, out));
|
|
|
|
MRK_RES(mrk_parser_parse_link(child, parser));
|
|
|
|
break;
|
|
|
|
case mrk_token_type_newline:
|
|
|
|
MRK_RES(mrk_ast_node_child_append(&child, out));
|
|
|
|
child->type = mrk_ast_node_type_space;
|
|
|
|
mrk_parser_advance(parser);
|
|
|
|
break;
|
|
|
|
case mrk_token_type_blank_line:
|
|
|
|
mrk_parser_advance(parser);
|
|
|
|
return mrk_err_ok;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return mrk_err_ok;
|
2024-03-12 20:51:48 +01:00
|
|
|
}
|