#include "mrk/parser_internal.h" void mrk_parser_open(mrk_parser *parser, mrk_lexer *lexer) { parser->lexer = lexer; // Prefill lookahead buffer for (size_t i = 0; i < MRK_PARSER_LOOKAHEAD_BUF_SIZE && !mrk_lexer_done(lexer); i++) { mrk_lexer_next(&parser->lookahead.buf[i], lexer); } } mrk_err mrk_parser_parse(mrk_ast_node **out, mrk_parser *parser) { mrk_ast_node *root; MRK_RES(mrk_ast_node_init(&root)); while (!mrk_lexer_done(parser->lexer)) { mrk_ast_node *child; MRK_RES(mrk_ast_node_child_append(&child, root)); MRK_RES(mrk_parser_parse_block(child, parser)); } *out = root; return mrk_err_ok; } mrk_err mrk_parser_parse_block(mrk_ast_node *out, mrk_parser *parser) { mrk_token t = mrk_parser_peek(parser); switch (t.type) { case mrk_token_type_header_start: MRK_RES(mrk_parser_parse_header(out, parser)); break; } if (!mrk_parser_done(parser)) { mrk_parser_eat(NULL, parser, mrk_token_type_blank_line); } return mrk_err_ok; } /* mrk_err mrk_parser_parse_ */ 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; out->args[0].num = mrk_token_len(header_token); // Parse subsections of header while (!mrk_parser_done(parser) && mrk_parser_peek(parser).type != mrk_token_type_blank_line) { 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; // Newlines are interpreted as spaces case mrk_token_type_newline: child->type = mrk_ast_node_type_space; mrk_parser_advance(parser); break; } } // Headers are blocks of their own, so they're delimited by blank lines /* while (!mrk_parser_done(parser) && */ /* (t = mrk_parser_peek(parser)).type != mrk_token_type_blank_line) { */ /* switch (t.type) { /1* case *1/ */ /* } */ /* } */ // Skip blank line mrk_parser_advance(parser); 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)); // Start in input buffer out->args[0].num = text_token.start; // End in input buffer out->args[1].num = text_token.end; return mrk_err_ok; }