Sign in

    moonttl

    MoonTTL is a high-performance RDF parsing and serialization library for MoonBit.

    nquads
    rdf
    Download zip
    Author
    Version
    0.2.0
    License
    Apache-2.0
    Last updated
    2 months ago
    Downloads
    400

    #MoonTTL

    MoonTTL 是一个使用 MoonBit 语言编写的高性能 RDF 解析与序列化库。本项目参考自 Rust 生态中的优秀库 Oxttl,旨在为 MoonBit 生态提供一套标准化、轻量级的语义网数据处理引擎。

    #特性

    • 多格式支持:完整支持 Turtle, TriG, N-Triples, N-Quads 和 N3 格式的解析与序列化(目前仅支持 N-Quads 格式)。
    • RDF 1.2 兼容:全面支持最新的 RDF 1.2 国际标准规范。
    • 高性能:基于状态机的词法分析器设计,提供高效的解析性能。
    • 轻量级:专注于核心解析功能,保持依赖最小化。

    #安装

    确保你的环境中已经安装了 MoonBit 工具链。

    在你的 moon.mod.json 中添加依赖:

    { "name": "your_username/your_project", "deps": [ "thy1016/moonttl" ] }

    #命令行工具

    #从字符串解析

    moon run src/cmd/main -- "<http://example.org/s> <http://example.org/p> <http://example.org/o> ."

    #从文件解析

    echo '<http://example.org/s> <http://example.org/p> <http://example.org/o> .' > test.nq moon run src/cmd/main -- -f test.nq

    #详细输出模式

    moon run src/cmd/main -- -v -f test.nq

    #命令行选项

    • -f, --file <path> - 指定输入文件路径
    • -v, --verbose - 启用详细输出模式
    • <input> - 直接输入 N-Quads 格式的字符串

    #N-Quads 格式说明

    N-Quads 是一种简洁的 RDF 四元组格式,每行一个语句:

    .

    其中 graph 部分可选,默认为默认图。

    示例:

    <http://example.org/s> <http://example.org/p> <http://example.org/o> .

    #示例代码

    let content = "<http://example.org/s> <http://example.org/p> <http://example.org/o> .\n"
    let data = @utf8.encode(content).to_array()

    let lexer = @lib.Lexer::Lexer(
    @lib.RdfLexer::RdfLexer(@lib.RdfMode::NTriples, false, []),
    data,
    true,
    @lib.MIN_BUFFER_SIZE,
    @lib.MAX_BUFFER_SIZE,
    Some(b"#"),
    0,
    0,
    )

    let logger = @lib.make_console_logger()

    let machine = @lib.NQuadsRecognizer::{
    current_state: @lib.NQuadsState::ExpectSubject,
    stack: [@lib.NQuadsState::ExpectSubject],
    emit_quad: false,
    temp_literal: None,
    lenient: false,
    debug_logger: logger,
    last_range: @lib.Range::default(),
    errors: [],
    }

    let context = @lib.RdfContext::NQuadsRecognizerContext(@lib.NQuadsRecognizerContext::{
    with_graph_name: true,
    lexer_options: { base_iri: None },
    })

    let generic_machine = @lib.GenericStateMachine::GenericStateMachine(
    machine,
    context,
    debug_logger=logger,
    )
    let parser = @lib.Parser::{
    lexer,
    engine: generic_machine,
    context,
    errors: [],
    }


    for ;; {
    match parser.parse_next() {
    Some(Ok(quad)) => println("Parsed: \{quad}")
    Some(Err(e)) => println("Error: \{e}")
    None => break
    }
    }

    #项目结构

    src/ ├── lexer_*.mbt # 词法分析器 ├── parser_*.mbt # 语法分析器 ├── iri.mbt # IRI 处理 ├── literal.mbt # 字面量处理 ├── langtag.mbt # 语言标签处理 └── tests/ # 测试文件

    #Examples

    #解析 N-Quads 文件

    运行示例程序:

    moon run src/examples/nquads
    输出示例:

    Written N-Quads content to: ./example.nq Parsing N-Quads file... [1] Quad<http://example.org/s1, http://example.org/p1, http://example.org/o1> [2] Quad<http://example.org/s2, http://example.org/p2, http://example.org/o2> [3] Quad<http://example.org/s3, http://example.org/p3, http://example.org/o3> [4] Error: InvalidTurtleToken - Unexpected end of input turtle .

    === Summary === Total quads parsed: 3

    该示例展示了:
    • 从字符串创建 N-Quads 内容并写入文件
    • 从文件读取并解析为二进制数据
    • 使用词法分析器和状态机解析 RDF 四元组
    • 错误处理和结果汇总

    #许可证声明

    W3C 测试套件中的测试文件在以下两种许可证下分发,使用时由被许可方二选一:

    • W3C 3-clause BSD License — 允许修改和集成到开发工具中,但禁止对修改后的测试断言性能声明或规范一致性。
    • W3C Test Suite License — 要求测试文件保持未修改状态,方可对外发布性能声明。

    本项目在开发测试和 CI 回归测试中采用 BSD 许可证 使用这些测试用例,并根据项目需求对测试框架进行了适配包装。如需了解 完整版权条款,请参阅 W3C Test Suites Licenses 官方页面。

    #测试覆盖范围

    当前 W3C 测试套件的覆盖情况:

    测试类别 总数 通过 状态 ━━━━━━━━━━━━━━━━━━ ━━━━━━ ━━━━━━ ━━━━━━━━━━━━━ N-Quads 正向测试 45 45 ✅ 全部通过 ────────────────── ────── ────── ───────────── N-Quads 负向测试 12 12 ✅ 全部通过 ────────────────── ────── ────── ───────────── 语法边界测试 8 8 ✅ 全部通过

    #性能基准

    #基准测试环境

    项目 版本/说明 ━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CPU Intel/AMD (测试环境) ────────── ──────────────────────────── 内存 8GB+ ────────── ──────────────────────────── 测试文件 1000 条 N-Quads (约 100KB)

    #性能对比

    实现 解析时间 每秒解析 每条耗时 ━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━ ━━━━━━━━━━━ ━━━━━━━━━━━ MoonTTL (MoonBit) 1.76 ms 568,612 0.0018 ms ──────────────────── ────────── ─────────── ─────────── Oxigraph (Rust) 2.00 ms 500,000 0.0020 ms ──────────────────── ────────── ─────────── ─────────── rdflib (Python) 17.89 ms 55,900 0.0179 ms ──────────────────── ────────── ─────────── ─────────── Apache Jena (Java) 2,734 ms 36,576 0.0273 ms ──────────────────── ────────── ─────────── ─────────── no-brain-scan (C) 0.16 ms 6,250,000 0.0002 ms ### MoonTTL 性能分析 === MoonBit 解析 test_1000.nq === 文件: test_1000.nq 文件大小: 103670 bytes === 性能数据 === Lexer: 515.532 µs (5000 tokens) ParserE: 575.14 µs (1000 quads) 验证: 1448.353 µs (1000 quads, 0 errors) 物化: 310.314 µs (1000 quads, 0 errors) === 总计 === 总时间: 1.76 ms 三元组数量: 1000 每秒解析: 568,612 每三元组: 0.0018 ms

    #运行基准测试

    cd src/benchmark ./run_all.sh

    #性能优化特性

    • 零拷贝设计:词法分析器基于字节数组切片,避免不必要的内存分配
    • 状态机驱动:使用有限状态机进行语法解析,保证 O(n) 时间复杂度
    • 前瞻解析:一次前瞻 5 个 token,减少函数调用开销
    • 批量物化:验证和物化分离,支持批量处理
    • 错误恢复:遇到错误自动跳过当前行,继续解析后续内容

    #贡献指南

    欢迎贡献代码、报告问题或提出建议!

    1. Fork 本仓库
    2. 创建您的特性分支 (git checkout -b feature/amazing-feature)
    3. 提交您的更改 (git commit -m 'Add some amazing feature')
    4. 推送到分支 (git push origin feature/amazing-feature)
    5. 开启一个 Pull Request

    #开发环境设置

    #克隆仓库

    git clone https://github.com/thy1016/moonttl.git cd moonttl

    #安装依赖

    moon update

    #运行测试

    moon test

    #构建项目

    moon build

    #许可证

    本项目采用以下许可证:

    • Apache License, Version 2.0, (LICENSE-APACHE or <http://www.apache.org/licenses/LICENSE-2.0>)

    您可自行选择适用的许可证。

    #贡献

    除非您另有明确声明,否则您有意提交给 MoonTTL 的任何贡献(按 Apache-2.0 许可证的定义)均应按上述方式双重许可,不附加任何其他条款或条件。

    IriParser

    type IriParser[A] =
    Parser
    [Char, Result[A, IriError]]

    A parser combinator

    Predicate

    type Predicate = ArrayView[Byte]

    Predicate = BytesView(只能是 IRI)

    Ref

    using @moonbitlang/core/ref { type Ref }

    A simple mutable reference type that allows you to store and modify a value of any type.

    test {
    let x = @ref.Ref(42)
    @test.assert_eq(x.val, 42)
    x.val = 100
    @test.assert_eq(x.val, 100)
    }

    ResParser

    type ResParser[A] = (Result[A, IriError],
    Seq
    [Char])?

    Span

    type Span = (Int, Int)

    DebugLogger

    pub trait DebugLogger {
    fn info(Self, String) -> Unit
    fn error(Self, String) -> Unit
    fn warn(Self, String) -> Unit
    }

    ErrOut

    pub trait ErrOut {
    fn message(self : Self) -> String
    fn err_kind(self : Self) -> String
    }

    ParserEngine

    pub trait ParserEngine {
    fn error_recovery_state(Self) -> Self
    fn create_pending(Self) -> PendingQuad
    fn step(Self, pending : PendingQuad, token : Token) -> StepResult
    fn is_complete(Self, pending : PendingQuad) -> Bool
    fn recognize_end(Self, pending : PendingQuad, results : Array[(Int, Int)]) -> Unit
    }

    IriError

    pub(all) suberror IriError {
    NoScheme(Int)
    InvalidScheme(Char, Int)
    InvalidCharacter(Char, Int)
    InvalidPath(Int)
    InvalidAuthority(String)
    InvalidPercentEncoding(Int)
    UnexpectedEnd(Int)
    } derive(
    Debug
    )

    impl Show for IriError
    impl ErrOut for IriError

    IriError::position

    fn IriError::position(self : IriError) -> Int

    LanguageTagParseError

    pub(all) suberror LanguageTagParseError {
    TagParseErr(TagParseErr)
    } derive(
    Debug
    )

    ParseError

    pub(all) suberror ParseError {
    InvalidErrMessage(String)
    InvalidToken(String, (Int, Int))
    } derive(
    Debug
    )

    NQuadsEngine 错误类型(包含位置信息)
    impl Show for ParseError

    TagParseErr

    pub(all) suberror TagParseErr {
    EmptyExtension
    EmptyPrivateUse
    ForbiddenChar
    InvalidSubtag(Int, StringView)
    InvalidLanguage
    SubtagTooLong
    EmptySubtag
    TooManyExtlangs
    InvalidLanguageLength
    } derive(
    Debug
    )

    impl Show for TagParseErr

    BaseDirection

    pub(all) enum BaseDirection {
    Ltr
    Rtl
    } derive(Eq, Hash, ToJson,
    Debug
    )

    ConsoleLogger

    type ConsoleLogger

    ExtensionsIterator

    pub(all) struct ExtensionsIterator {
    input : StringView
    subtags : Array[StringView]
    index : Int
    }

    GraphName

    pub(all) enum GraphName {
    None
    Iri(ArrayView[Byte])
    } derive(Eq,
    Debug
    )

    图名

    IriR

    pub(all) struct IriR {
    scheme : StringView
    authority : StringView?
    path : StringView
    query : StringView?
    fragment : StringView?
    } derive(Default, Eq,
    Debug
    )

    IriR::IriR

    fn IriR::IriR(scheme : StringView, authority : StringView?, path : StringView, query : StringView?, fragment : StringView?) -> IriR

    IriR::into_string

    fn IriR::into_string(self : IriR) -> String

    IriR::parse

    fn IriR::parse(_self : IriR, s : String) -> Result[IriR, IriError]

    IriR::parse_unchecked

    fn IriR::parse_unchecked(_self : IriR, s : String) -> IriR

    IriR::relativize

    fn IriR::relativize(self : IriR, target : IriR) -> Result[IriR, IriError]

    IriR::resolve

    fn IriR::resolve(self : IriR, ref_iri : String, remove_dot_segments? : Bool) -> Result[IriR, IriError]

    合并 IRI

    IriR::resolve_unchecked

    fn IriR::resolve_unchecked(self : IriR, ref_iri : String, remove_dot_segments? : Bool) -> IriR

    LanguageTag

    pub(all) struct LanguageTag {
    tag : StringView
    positions : TagElementsPositions
    } derive(Default, Eq, Hash,
    Debug
    )

    impl Show for LanguageTag

    LanguageTag::extended_language

    fn LanguageTag::extended_language(self : LanguageTag) -> StringView?

    LanguageTag::extended_language_subtags

    fn LanguageTag::extended_language_subtags(self : LanguageTag) -> Array[StringView]

    LanguageTag::extension

    fn LanguageTag::extension(self : LanguageTag) -> StringView?

    LanguageTag::extension_subtags

    fn LanguageTag::extension_subtags(self : LanguageTag) -> ExtensionsIterator

    LanguageTag::full_language

    fn LanguageTag::full_language(self : LanguageTag) -> StringView

    LanguageTag::into_str

    fn LanguageTag::into_str(self : LanguageTag) -> String

    LanguageTag::parse

    fn LanguageTag::parse(tag : StringView) -> Result[LanguageTag, TagParseErr]

    LanguageTag::parse_and_normalize

    fn LanguageTag::parse_and_normalize(tag : StringView) -> Result[LanguageTag, TagParseErr]

    LanguageTag::primary_language

    fn LanguageTag::primary_language(self : LanguageTag) -> StringView?

    LanguageTag::private_use

    fn LanguageTag::private_use(self : LanguageTag) -> StringView?

    LanguageTag::private_use_subtags

    fn LanguageTag::private_use_subtags(self : LanguageTag) -> Array[StringView]

    LanguageTag::region

    fn LanguageTag::region(self : LanguageTag) -> StringView?

    LanguageTag::script

    fn LanguageTag::script(self : LanguageTag) -> StringView?

    LanguageTag::variant

    fn LanguageTag::variant(self : LanguageTag) -> StringView?

    LanguageTag::variant_subtags

    fn LanguageTag::variant_subtags(self : LanguageTag) -> Array[StringView]

    Lexerc

    pub(all) struct Lexerc {
    ptr :
    Ref
    [Void]
    data : FixedArray[Byte]
    offset : Int
    token_buf : FixedArray[Byte]
    }

    MoonBit 词法分析器

    Lexerc::data

    fn Lexerc::data(self : Lexerc) -> FixedArray[Byte]

    获取原始数据引用

    Lexerc::destroy

    fn Lexerc::destroy(self : Lexerc) -> Unit

    销毁词法分析器

    Lexerc::extract

    fn Lexerc::extract(self : Lexerc, span : (Int, Int)) -> String

    Lexerc::extract_iri

    fn Lexerc::extract_iri(self : Lexerc, token : Token) -> ArrayView[Byte]

    Lexerc::extract_literal

    fn Lexerc::extract_literal(self : Lexerc, token : Token) -> ArrayView[Byte]

    Lexerc::is_end

    fn Lexerc::is_end(self : Lexerc) -> Bool

    检查是否到达末尾

    Lexerc::new

    fn Lexerc::new(data : FixedArray[Byte]) -> Lexerc

    创建词法分析器

    Lexerc::next

    fn Lexerc::next(self : Lexerc) -> Token?

    获取下一个 Token

    Lexerc::position

    fn Lexerc::position(self : Lexerc) -> Int

    获取当前位置

    Lexerc::remaining

    fn Lexerc::remaining(self : Lexerc) -> Int

    获取剩余数据长度

    Lexerc::reset

    fn Lexerc::reset(self : Lexerc) -> Unit

    重置词法分析器

    MuteLogger

    type MuteLogger

    NQuadsEngine

    pub(all) struct NQuadsEngine {
    lexer : Lexerc
    pending : PendingQuad
    }

    NQuadsEngine - 直接对接 Lexerc,管理 PendingQuad 组装和错误收集

    NQuadsEngine::from_bytes

    fn NQuadsEngine::from_bytes(data : FixedArray[Byte]) -> NQuadsEngine

    从字节数组创建 NQuadsEngine

    NQuadsEngine::from_string

    fn NQuadsEngine::from_string(s : String) -> NQuadsEngine

    从字符串创建 NQuadsEngine

    NQuadsEngine::new

    创建空 NQuadsEngine

    Object

    pub(all) enum Object {
    Iri(ArrayView[Byte])
    BNode(ArrayView[Byte])
    Literal(ArrayView[Byte])
    PrefName(ArrayView[Byte])
    } derive(Eq,
    Debug
    )

    宾语类型
    impl Show for Object

    Parser

    pub struct Parser[E] {
    lexer : Lexerc
    engine : E
    pending : PendingQuad
    errors : Array[ParseError]
    data : ArrayView[Byte]
    }

    Parser::data

    fn[E] Parser::data(self : Parser[E]) -> ArrayView[Byte]

    Parser::from_bytes

    fn[E : ParserEngine] Parser::from_bytes(data : FixedArray[Byte], engine : E) -> Parser[E]

    Parser::get_errors

    fn[E] Parser::get_errors(self : Parser[E]) -> Array[ParseError]

    Parser::new

    fn[E : ParserEngine] Parser::new(lexer : Lexerc, engine : E, data : ArrayView[Byte]) -> Parser[E]

    Parser::next

    fn[E : ParserEngine] Parser::next(self : Parser[E]) -> Result[PendingQuad, ParseError]?

    ParserIter

    pub struct ParserIter[E] {
    parser : Parser[E]
    }

    ParserIter::new

    fn[E] ParserIter::new(parser : Parser[E]) -> ParserIter[E]

    ParserIter::next

    fn[E : ParserEngine] ParserIter::next(self : ParserIter[E]) -> Result[PendingQuad, ParseError]?

    PendingQuad

    pub struct PendingQuad {
    subj : (Int, Int)?
    pred : (Int, Int)?
    obj : (Int, Int)?
    graph : (Int, Int)?
    has_dot : Bool
    state : PendingState
    line : Int
    } derive(Eq,
    Debug
    )

    impl Show for PendingQuad

    PendingQuad::compute_span

    fn PendingQuad::compute_span(self : PendingQuad) -> (Int, Int)

    获取总 span

    PendingQuad::default

    fn PendingQuad::default() -> PendingQuad

    PendingQuad::is_complete

    fn PendingQuad::is_complete(self : PendingQuad) -> Bool

    检查是否完整

    PendingQuad::reset

    fn PendingQuad::reset(self : PendingQuad) -> Unit

    重置状态

    PendingState

    pub(all) enum PendingState {
    ExpectSubject
    ExpectPredicate
    ExpectObject
    ExpectDotOrGraph
    ExpectGraph
    ExpectDot
    Complete
    } derive(Eq,
    Debug
    )

    Quad 组装状态机 PendingQuad 的组装状态

    QuadEmit

    pub(all) struct QuadEmit {
    subject : Subject
    predicate : ArrayView[Byte]
    object : Object
    graph_name : GraphName
    line : Int
    } derive(Eq,
    Debug
    )

    N-Quads Quad
    impl Show for QuadEmit

    QuadSpan

    pub struct QuadSpan {
    subj : (Int, Int)
    pred : (Int, Int)
    obj : (Int, Int)
    graph : (Int, Int)?
    line : Int
    subj_type : TermType
    obj_type : TermType
    } derive(
    Debug
    )

    impl Show for QuadSpan

    Range

    pub(all) struct Range {
    start : Int
    end : Int
    } derive(Default, Eq,
    Debug
    )

    Range::Range

    fn Range::Range(start : Int, end : Int) -> Range

    Serializer

    pub struct Serializer {
    data : ArrayView[Byte]
    mode : StringView
    }

    Serializer::new

    fn Serializer::new(data : ArrayView[Byte], mode? : StringView) -> Serializer

    Serializer::serialize

    fn Serializer::serialize(self : Serializer, quad : QuadEmit) -> String

    序列化单个 Quad

    Serializer::serialize_all

    fn Serializer::serialize_all(self : Serializer, quads : Array[QuadEmit]) -> String

    SliceParser

    pub struct SliceParser[E] {
    inner : ParserIter[E]
    data : ArrayView[Byte]
    lenient : Bool
    }

    SliceParser::lenient

    fn[E] SliceParser::lenient(self : SliceParser[E]) -> SliceParser[E]

    链式调用设置宽松模式

    SliceParser::new

    fn[E] SliceParser::new(parser : Parser[E], data : ArrayView[Byte], lenient? : Bool) -> SliceParser[E]

    SliceParser::next

    fn[E : ParserEngine] SliceParser::next(self : SliceParser[E]) -> Result[QuadSpan, ParseError]?

    实现 Iter trait

    SliceParser::parse_all

    fn[E : ParserEngine] SliceParser::parse_all(self : SliceParser[E]) -> (Array[QuadSpan], Array[ParseError])

    解析全部

    StepResult

    pub(all) enum StepResult {
    Continue
    Emit
    SkipLine
    Error(ParseError)
    }

    解析步骤结果

    Subject

    pub(all) enum Subject {
    Iri(ArrayView[Byte])
    BNode(ArrayView[Byte])
    PrefName(ArrayView[Byte])
    } derive(Eq,
    Debug
    )

    主语类型
    impl Show for Subject

    SubtagType

    pub(all) enum SubtagType {
    PrivateUseIntro
    ExtensionIntro(Char)
    Alphabetic(Int)
    Numeric(Int)
    Alphanumeric(Int)
    Invalid
    }

    TagElementsPositions

    type TagElementsPositions derive(Default, Eq, Hash,
    Debug
    )

    TermType

    pub(all) enum TermType {
    Unknown
    Iri
    BNode
    Literal
    PrefName
    } derive(Eq,
    Debug
    )

    impl Show for TermType

    Token

    pub(all) enum Token {
    Dot((Int, Int))
    Semicolon((Int, Int))
    Comma((Int, Int))
    Iri((Int, Int))
    Literal((Int, Int))
    BlankNode((Int, Int))
    PrefName((Int, Int))
    Unknown((Int, Int))
    EOF(Int)
    } derive(
    Debug
    )

    impl Show for Token

    Void

    type Void

    MAX_BUFFER_SIZE

    let MAX_BUFFER_SIZE : Int

    MIN_BUFFER_SIZE

    let MIN_BUFFER_SIZE : Int

    MIN_PARALLEL_CHUNK_SIZE

    let MIN_PARALLEL_CHUNK_SIZE : Int

    array_to_view

    fn array_to_view(arr : ArrayView[Byte]) -> BytesView

    array_view_has_prefix

    fn array_view_has_prefix(data : ArrayView[Byte], prefix : Bytes) -> Bool

    array_view_memchr

    fn array_view_memchr(target : Byte, data : ArrayView[Byte]) -> Int?

    array_view_memchr2

    fn array_view_memchr2(c1 : Byte, c2 : Byte, data : ArrayView[Byte]) -> Int?

    classify_subtag

    fn classify_subtag(s : StringView) -> SubtagType

    end_offset

    fn end_offset(span : (Int, Int)) -> Int

    获取 span 的结束偏移

    find_newline_in_range

    fn find_newline_in_range(bytes : BytesView, start : Int, end : Int) -> Int?

    在指定范围内搜索换行符,返回换行符的绝对位置

    fn_remove_dot_segments

    fn fn_remove_dot_segments(path : StringView) -> StringView

    from_str_radix

    fn from_str_radix(s : String, radix : Int) -> Result[UInt, String]

    get_ntriples_file_chunks

    async fn get_ntriples_file_chunks(file :
    File
    , file_size : Int64, n_chunks : Int) -> Result[Array[(Int64, Int64)], String]

    get_ntriples_slice_chunks

    fn get_ntriples_slice_chunks(bytes : Array[Byte], n_chunks : Int) -> Array[(Int, Int)]

    get_turtle_slice_chunks

    fn get_turtle_slice_chunks(bytes : Array[Byte], n_chunks : Int) -> Array[(Int, Int)]

    iri_illegal_table

    let iri_illegal_table : FixedArray[Int]

    非法字符查表:索引为字节值 (0-255),值为 1 表示非法

    is_pchar

    fn is_pchar(c : Char) -> Bool

    is_unreserved

    fn is_unreserved(c : Char) -> Bool

    is_valid_hex_string

    fn is_valid_hex_string(hex : String) -> Bool

    lexer_create

    fn lexer_create(data : FixedArray[Byte], len : Int) ->
    Ref
    [Void]

    创建词法分析器

    lexer_destroy

    fn lexer_destroy(lexer :
    Ref
    [Void]) -> Unit

    销毁词法分析器

    lexer_next

    fn lexer_next(lexer :
    Ref
    [Void], token_buf : FixedArray[Byte]) -> Bool

    获取下一个 Token(写入 Bytes 缓冲区)

    make_console_logger

    fn make_console_logger() -> ConsoleLogger

    make_mute_logger

    fn make_mute_logger() -> MuteLogger

    materialize_all

    fn materialize_all(quads : Array[QuadSpan], data : ArrayView[Byte]) -> (Array[QuadEmit], Array[ParseError])

    批量物化(优化:减少函数调用开销)

    materialize_quad

    fn materialize_quad(quad : QuadSpan, data : ArrayView[Byte]) -> Result[QuadEmit, ParseError]

    物化 Quad(批量优化)

    nquads_parser

    fn nquads_parser(data : FixedArray[Byte]) -> Parser[NQuadsEngine]

    parse_duration

    fn parse_duration(s : String) -> Result[String, String]

    parse_iri

    let parse_iri :
    Parser
    [Char, Result[IriR, IriError]]

    完整的 IRI 解析器

    parse_primary_language

    fn parse_primary_language(subtag : StringView) -> Result[StringView, TagParseErr]

    parse_xsd_date

    fn parse_xsd_date(s : String) -> Result[String, String]

    remove_dot_segments_from_array

    fn remove_dot_segments_from_array(segments : Array[String]) -> Array[String]

    validate_iri

    fn validate_iri(data : ArrayView[Byte], span : (Int, Int)) -> Result[(Int, Int), ParseError]

    IRI 验证