Add a parser for a single node

This commit is contained in:
Renaud Casenave-Péré 2022-12-09 22:05:12 +01:00
parent fb517d349c
commit 0b2e063eaf
2 changed files with 33 additions and 1 deletions

View file

@ -1,6 +1,7 @@
(uiop:define-package :sextant/org/parser
(:use :cl :alexandria :sextant/org/nodes)
(:export #:parse-document))
(:export #:parse-document
#:parse-node))
(in-package :sextant/org/parser)
(defun parse-document (spec)
@ -8,3 +9,7 @@
(string spec)
((or pathname stream) (read-file-into-string spec)))))
(time (lexy::parse-document str))))
(defun parse-node (node)
(time (lexy::parse-node (with-output-to-string (stream)
(org-print node stream)))))

View file

@ -42,6 +42,32 @@ namespace sextant
return ECL_NIL;
}
cl_object parse_node(cl_object l_str)
{
assert(ECL_STRINGP(l_str));
std::string str;
if (ECL_BASE_STRING_P(l_str))
str = std::string((char*)l_str->base_string.self, l_str->base_string.fillp);
else
{
ecl_character* l_p = l_str->string.self;
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
str = converter.to_bytes((char32_t*)l_p, (char32_t*)(l_p + l_str->string.dim));
}
auto input = lexy::string_input<lexy::utf8_encoding>(str);
auto result = lexy::parse<grammar::org_node>(input, lexy_ext::report_error);
if (!result)
return ECL_NIL;
if (result.has_value())
return result.value();
return ECL_NIL;
}
void init_parser_lib()
{
cl_object lexy = ecl_make_constant_base_string("LEXY", 4);
@ -49,6 +75,7 @@ namespace sextant
ecl_make_package(lexy, ECL_NIL, ECL_NIL, ECL_NIL);
si_select_package(lexy);
ecl_def_c_function(ecl_read_from_cstring("parse-document"), (cl_objectfn_fixed)parse_document, 1);
ecl_def_c_function(ecl_read_from_cstring("parse-node"), (cl_objectfn_fixed)parse_node, 1);
}
}