MoonTTL is a high-performance RDF parsing and serialization library for MoonBit.
{
"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.nqmoon run src/cmd/main -- -v -f test.nq<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.RdfLexerMode::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/ # 测试文件moon run src/examples/nquadsWritten 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: 3test {
let x = @ref.Ref(42)
@test.assert_eq(x.val, 42)
x.val = 100
@test.assert_eq(x.val, 100)
}pub trait DebugLogger {
fn info(Self, String) -> Unit
fn error(Self, String) -> Unit
fn warn(Self, String) -> Unit
}pub trait ErrOut {
fn message(self : Self) -> String
fn err_kind(self : Self) -> String
}pub trait GenMachine {
fn initial_state(Self) -> RdfState
fn transition(Self, state : RdfState, event : LocatedToken, context : RdfContext) -> Result[(Self, RdfState, DataAction), RuleRecognizerError]
fn current_state(Self) -> RdfState
fn step(Self, event : LocatedToken) -> Self
fn reset(Self) -> Self
fn is_accepting(Self) -> Bool
fn context(Self) -> RdfContext
fn[ST : StateWrapper] set_current_state(Self, state : ST) -> Self
fn error_recovery_statemachine(Self) -> Self
fn accumulate(Self, dw : DataWorld, action : DataAction) -> (Self, DataWorld)
fn get_and_clear_output(Self, dw : DataWorld) -> (Self, RdfOut?)
}pub trait RuleRecognizer {
fn error_recovery_state(Self) -> Self
fn recognize_end(Self, context : RdfContext, results : Array[RdfOut]) -> Unit
fn lexer_options(context : RdfContext) -> LexerOptions?
}pub trait TokenRecognizer {
fn recognize_next_token(Self, data : ArrayView[Byte], is_ending : Bool, options : LexerOptions?, location_pos : SourcePos) -> (Int, Result[LocatedToken, TokenRecognizerError])?
}pub(all) suberror IriError {
NoScheme(Int)
InvalidScheme(Char, Int)
InvalidCharacter(Char, Int)
InvalidPath(Int)
InvalidAuthority(String)
InvalidPercentEncoding(Int)
UnexpectedEnd(Int)
} derive(Debug)pub(all) suberror LexerError {
OutOfMemory(String)
IoReadError(String)
SyntaxError(String)
}pub(all) suberror TagParseErr {
EmptyExtension
EmptyPrivateUse
ForbiddenChar
InvalidSubtag(Int, StringView)
InvalidLanguage
SubtagTooLong
EmptySubtag
TooManyExtlangs
InvalidLanguageLength
} derive(Debug)impl Show for TagParseErrpub(all) suberror TokenRecognizerError {
Invalid
InvalidFormat(ArrayView[Byte], Range)
InvalidToken(String, ArrayView[Byte], Range)
InvalidCharacter(ArrayView[Byte], Range)
IncompleteEscapeSequence(ArrayView[Byte], Range)
InvalidEscapeSequence(ArrayView[Byte], Range)
UnsupportedFeature(ArrayView[Byte], Range)
IriTruncated(ArrayView[Byte], Range)
IriParsingError(String, Range)
UnexpectedEndOfInput(ArrayView[Byte], Range)
InvalidErrMessage(ArrayView[Byte], Range, String)
} derive(Debug)async fn[TR : TokenRecognizer, RR : GenMachine] AsyncReaderIterator::next(self : AsyncReaderIterator[TR, RR]) -> Result[RdfOut, LexerError]?async fn[RL : TokenRecognizer] AsyncReaderNQuadsParser::next(self : AsyncReaderNQuadsParser[RL]) -> Result[RdfOut, LexerError]?async fn[RL : TokenRecognizer] AsyncReaderNTriplesParser::next(self : AsyncReaderNTriplesParser[RL]) -> Result[RdfOut, LexerError]?pub struct AsyncWriterNQuadsSerializer[W] {
buffer_writer : BufferedWriter[W]
low_level_writer : LowLevelNQuadsSerializer
}async fn[W : Writer] AsyncWriterNQuadsSerializer::finish(self : AsyncWriterNQuadsSerializer[W]) -> Result[BufferedWriter[W], Unit]async fn[W : Writer] AsyncWriterNQuadsSerializer::serialize_quad(self : AsyncWriterNQuadsSerializer[W], q : Quad) -> Result[AsyncWriterNQuadsSerializer[W], SerializationError]pub struct AsyncWriterNTriplesSerializer[W] {
buffer_writer : BufferedWriter[W]
low_level_writer : LowLevelNTriplesSerializer
}async fn[W : Writer] AsyncWriterNTriplesSerializer::finish(self : AsyncWriterNTriplesSerializer[W]) -> Result[BufferedWriter[W], Unit]fn[W] AsyncWriterNTriplesSerializer::serialize_triple(self : AsyncWriterNTriplesSerializer[W], t : Triple) -> Result[String, Unit]impl Show for BaseDirectionpub(all) enum CharClass {
Other
Space
Newline
LAngle
RAngle
Colon
Semicolon
Period
Comma
LParen
RParen
LBracket
RBracket
LBrace
RBrace
Quote
TripleQuote
At
QuestionMark
Plus
Minus
Underscore
Percent
Hash
Slash
Backslash
Star
Eq
Less
Greater
Caret
Pipe
Tilde
Exclamation
Dollar
Ampersand
Apostrophe
LtLt
GtGt
CaretCaret
LBracePipe
PipeRBrace
LtLtLParen
RParenGtGt
LtMinus
EqGt
LtEq
LtLtRParen
ColonColon
ColonSlash
Digit
LowerU
UpperU
} derive(Eq, Hash, Debug)pub(all) enum Command {
ParseQuad(NamedOrBlankNodeRef, NamedNodeRef, TermRef, GraphNameRef)
ParseTriple(NamedOrBlankNodeRef, NamedNodeRef, TermRef)
ParseLiteralQuad(NamedOrBlankNodeRef, NamedNodeRef, String, String, GraphNameRef)
ParseTypedLiteral(NamedOrBlankNodeRef, NamedNodeRef, String, NamedNodeRef, GraphNameRef)
ParseBlankSubject(BlankNodeRef, NamedNodeRef, TermRef, GraphNameRef)
ParseBlankObject(NamedOrBlankNodeRef, NamedNodeRef, BlankNodeRef, GraphNameRef)
} derive(Eq, Debug)pub(all) enum DataAction {
NoOp
AddSubject(NamedOrBlankNodeRef)
AddPredicate(NamedNodeRef)
AddObject(TermRef)
SetTempLiteral(String)
SetGraphName(GraphNameRef)
EmitQuad
EmitQuadWithLiteral(LiteralKind)
EmitQuadWithTempLiteral(NamedNodeRef)
PushStack(NQuadsState)
ClearAccumulator
FinalizeLiteral(LiteralKind)
FinalizeQuotedTriple
}pub(all) struct DataWorld {
subjects : Array[NamedOrBlankNodeRef]
predicates : Array[NamedNodeRef]
objects : Array[TermRef]
temp_literal : String?
finalize_literal : LiteralKind?
graph_name : GraphNameRef?
} derive(Eq, Hash, Debug)fn DataWorld::DataWorld(subjects : Array[NamedOrBlankNodeRef], predicates : Array[NamedNodeRef], objects : Array[TermRef], temp_literal : String?, finalize_literal : LiteralKind?, graph_name : GraphNameRef?) -> DataWorldpub(all) struct GenericStateMachine[M] {
machine : M
context : RdfContext
outputs : Array[RdfOut]
data_world : DataWorld
debug_logger : &DebugLogger
lexer_errors : Array[(String, ArrayView[Byte], Range)]
}impl GenMachine for GenericStateMachine[M]fn[M : GenMachine] accumulate(self : GenericStateMachine[M], dw : DataWorld, da : DataAction) -> (GenericStateMachine[M], DataWorld)fn[M : GenMachine] error_recovery_statemachine(self : GenericStateMachine[M]) -> GenericStateMachine[M]fn[M : GenMachine] get_and_clear_output(self : GenericStateMachine[M], data_world : DataWorld) -> (GenericStateMachine[M], RdfOut?)fn[M : GenMachine, ST : StateWrapper] set_current_state(self : GenericStateMachine[M], state : ST) -> GenericStateMachine[M]fn[M : GenMachine] step(self : GenericStateMachine[M], event : LocatedToken) -> GenericStateMachine[M]fn[M] GenericStateMachine::GenericStateMachine(machine : M, context : RdfContext, debug_logger? : &DebugLogger) -> GenericStateMachine[M]fn[M] GenericStateMachine::remove_first_output(self : GenericStateMachine[M]) -> GenericStateMachine[M]fn[M : GenMachine] GenericStateMachine::run(self : GenericStateMachine[M], events : Array[LocatedToken]) -> Result[Array[DataAction], RuleRecognizerError]?fn[M] GenericStateMachine::set_context(self : GenericStateMachine[M], new_context : RdfContext) -> GenericStateMachine[M]pub(all) enum GraphNameRef {
DefaultGraph
NamedNodeRef(NamedNodeRef)
BlankNodeRef(BlankNodeRef)
} derive(Eq, Hash, Debug)pub(all) struct LanguageTag {
tag : StringView
positions : TagElementsPositions
} derive(Default, Eq, Hash, Debug)impl Show for LanguageTagpub(all) enum LexAction {
Continue
Skip
EmitToken
EmitTokenWithDirection(BaseDirection?)
SetState(LexStateMachine)
StartCapture
AppendCapture
EndCapture
EndLongStringCapture
EmitError(String)
Done
} derive(Eq, Hash, Debug)pub(all) struct LexContext {
data_buffer : ArrayView[Byte]
position : Int
state : LexStateMachine
capture_start : Int
capture_current : Int
state_stack : Array[LexStateMachine]
is_ending : Bool
captured : String?
escape_quote : EscapeQuote
has_error : Bool
error_message : String?
prev_char : Byte?
}pub(all) enum LexStateMachine {
Start
InIri
InEsc
InStringEscHex4
InStringEscHex8
InBlank
InBlankLabel
InString
InStringEsc
InLongStringEsc
InLongStringQuote
InLongStringQuoteContent
InLongStringQuoteEnd
InLongStringSingleQuote
InLongStringSingleQuoteContent
InLongStringSingleQuoteEnd
InNumber
InInteger
InDecimal
InDecimalStart
InDouble
InExponent
InLangTag
InLangTagExt
InVariable
InPnamePrefix
InPnameLocalStart
InPnameLocal
InKeyword
InPunct
SkipLineComment
SkipBlockComment(Int)
Error
Done
} derive(Eq, Hash, Debug)impl Show for LexStateMachineasync fn[RL] Lexer::extend_from_async_read(self : Lexer[RL], reader : &Reader) -> Result[Int, LexerError]async fn[RL] Lexer::extend_from_reader(self : Lexer[RL], reader : &Reader) -> Result[Int, LexerError]fn[RL] Lexer::location_from_buffer_offset_range(self : Lexer[RL], offset_range : Range) -> SourceRangefn[RL : TokenRecognizer] Lexer::parse_next(self : Lexer[RL], options : LexerOptions?) -> Result[LocatedToken, TokenRecognizerError]?fn Literal::new_directional_language_tagged_literal(value : String, language : String, direction : BaseDirection) -> Result[Literal, LanguageTagParseError]fn Literal::new_directional_language_tagged_literal_unchecked(value : StringView, language : LanguageTag, direction : BaseDirection) -> Literalfn Literal::new_language_tagged_literal(value : String, language : String) -> Result[Literal, LanguageTagParseError]pub(all) enum LiteralKind {
Simple
Lang(LanguageTag, BaseDirection)
Typed(String, NamedNodeRef)
} derive(Eq, Hash, Debug)impl Show for LiteralKindimpl Show for LiteralReffn LiteralRef::new_directional_language_tagged_literal_unchecked(value : String, language : LanguageTag, direction : BaseDirection) -> LiteralReffn LiteralRef::new_language_tagged_literal_unchecked(value : String, language : StringView) -> LiteralRefpub(all) enum LiteralRefContent {
String(StringView)
LanguageTaggedString(value~ : String, language~ : StringView)
DirectionalLanguageTaggedString(value~ : StringView, language~ : StringView, direction~ : BaseDirection)
TypedLiteral(value~ : String, datatype~ : NamedNodeRef)
} derive(Eq, Hash, Debug)impl Show for LocatedTokenfn[RL] LowLevelNQuadsParser::extend_from_slice(self : LowLevelNQuadsParser[RL], other : Array[Byte]) -> Unitfn[RL : TokenRecognizer] LowLevelNQuadsParser::parse_next(self : LowLevelNQuadsParser[RL]) -> Result[Quad, TurtleError]?fn LowLevelNQuadsSerializer::serialize_quad(_self : LowLevelNQuadsSerializer, q : Quad) -> Result[String, Unit]fn LowLevelNTriplesParser::extend_from_slice(self : LowLevelNTriplesParser[RdfLexer], other : Array[Byte]) -> Unitfn[RL : TokenRecognizer] LowLevelNTriplesParser::parse_next(self : LowLevelNTriplesParser[RL]) -> Result[Triple, TurtleError]?fn LowLevelNTriplesSerializer::serialize_triple(_self : LowLevelNTriplesSerializer, t : Triple) -> Result[String, Unit]pub(all) enum N3Token {
Iri(String)
PrefixedName(prefix~ : String, localx~ : String, might_be_invalid_iri~ : Bool)
Variable(String)
BlankNodeLabel(String)
String(String)
LongString(String)
Integer(String)
Decimal(String)
Double(String)
LangTag(language~ : String, direction~ : BaseDirection?)
Punctuation(String)
PlainKeyword(String)
LineJump
End
} derive(Eq, Debug)pub(all) enum NQuadsAction {
PushSubject(NamedOrBlankNodeRef)
PushPredicate(NamedNodeRef)
PushObject(TermRef)
SetTempLiteral(String)
FinalizeSimpleLiteral
FinalizeLangLiteral(String, BaseDirection)
SetGraphName(NamedOrBlankNodeRef)
EmitQuad
EmitQuadWithGraphName
PushStack(NQuadsState)
PopStack
FinalizeQuotedTriple
SetError(RuleRecognizerError)
ClearAccumulator
}fn NQuadsParser::for_async_reader(self : NQuadsParser, reader : &Reader) -> AsyncReaderNQuadsParser[RdfLexer]fn NQuadsParser::for_slice(self : NQuadsParser, slice : BytesView) -> SliceNQuadsParser[NQuadsRecognizer]async fn NQuadsParser::split_file_for_parallel_parsing(self : NQuadsParser, path : String, target_parallelism : Int64) -> Result[Array[SliceNQuadsParser[NQuadsRecognizer]], String]fn NQuadsParser::split_slice_for_parallel_parsing(self : NQuadsParser, slice : BytesView, target_parallelism : Int) -> Array[SliceNQuadsParser[NQuadsRecognizer]]pub(all) struct NQuadsRecognizer {
current_state : NQuadsState
stack : Array[NQuadsState]
emit_quad : Bool
temp_literal : String?
lenient : Bool
debug_logger : &DebugLogger
last_range : Range
errors : Array[RuleRecognizerError]
}impl GenMachine for NQuadsRecognizerfn accumulate(self : NQuadsRecognizer, data_world : DataWorld, action : DataAction) -> (NQuadsRecognizer, DataWorld)fn get_and_clear_output(self : NQuadsRecognizer, data_world : DataWorld) -> (NQuadsRecognizer, RdfOut?)fn transition(self : NQuadsRecognizer, state : RdfState, event : LocatedToken, _context : RdfContext) -> Result[(NQuadsRecognizer, RdfState, DataAction), RuleRecognizerError]impl RuleRecognizer for NQuadsRecognizerfn NQuadsRecognizer::new_parser(data : Array[Byte], with_graph_name : Bool, lenient : Bool, debug_logger? : &DebugLogger) -> Parser[RdfLexer, NQuadsRecognizer]fn[W] NQuadsSerializer::for_async_writer(self : NQuadsSerializer, buffer_writer : BufferedWriter[W]) -> AsyncWriterNQuadsSerializer[W]fn[W] NQuadsSerializer::for_writer(self : NQuadsSerializer, writer : W) -> WriterNQuadsSerializer[W]fn NTriplesParser::for_async_reader(self : NTriplesParser, reader : &Reader) -> AsyncReaderNTriplesParser[RdfLexer]fn NTriplesParser::for_reader(self : NTriplesParser, reader : &Reader) -> ReaderNTriplesParser[RdfLexer]fn NTriplesParser::for_slice(self : NTriplesParser, slice : BytesView) -> SliceNTriplesParser[NQuadsRecognizer]async fn NTriplesParser::split_file_for_parallel_parsing(self : NTriplesParser, path : String, target_parallelism : Int64) -> Result[Array[SliceNTriplesParser[NQuadsRecognizer]], String]fn NTriplesParser::split_slice_for_parallel_parsing(self : NTriplesParser, slice : BytesView, target_parallelism : Int) -> Array[SliceNTriplesParser[NQuadsRecognizer]]fn[W] NTriplesSerializer::for_async_writer(self : NTriplesSerializer, buffer_writer : BufferedWriter[W]) -> AsyncWriterNTriplesSerializer[W]fn[W] NTriplesSerializer::for_writer(self : NTriplesSerializer, writer : W) -> WriterNTriplesSerializer[W]impl Show for NamedOrBlankNodepub enum NamedOrBlankNodeRef {
NamedNodeRef(NamedNodeRef)
BlankNodeRef(BlankNodeRef)
} derive(Eq, Hash, Debug)pub(all) struct Parser[TR, M] {
lexer : Lexer[TR]
engine : GenericStateMachine[M]
context : RdfContext
errors : Array[RuleRecognizerError]
}fn[TR, M] Parser::Parser(lexer : Lexer[TR], engine : GenericStateMachine[M], context : RdfContext) -> Parser[TR, M]fn[TR, RR] Parser::for_async_reader(self : Parser[TR, RR], reader : &Reader) -> AsyncReaderIterator[TR, RR]fn[TR : TokenRecognizer, M : GenMachine] Parser::parse_next(self : Parser[TR, M]) -> Result[RdfOut, TokenRecognizerError]?fn[TR, M : GenMachine] Parser::try_finish(self : Parser[TR, M]) -> Result[RdfOut, TokenRecognizerError]?pub struct QuadRef {
subject : NamedOrBlankNodeRef
predicate : NamedNodeRef
object : TermRef
graph_name : GraphNameRef
}pub(all) enum RdfFeature {
RelativeIri
Numbers
Prefixes
Variables
NonAsciiIri
StringEscapes
LangTags
LongStrings
PunctuationList
}impl TokenRecognizer for RdfLexerfn recognize_next_token(self : RdfLexer, data_buffer : ArrayView[Byte], is_ending : Bool, _options : LexerOptions?, location_pos : SourcePos) -> (Int, Result[LocatedToken, TokenRecognizerError])?fn RdfLexer::RdfLexer(mode : RdfLexerMode, lenient : Bool, _data_buffer : ArrayView[Byte], debug_logger? : &DebugLogger) -> RdfLexerfn RdfLexer::execute_action(self : RdfLexer, action : LexAction, ctx : LexContext, current : Byte, _data_buffer : ArrayView[Byte]) -> (LexAction, LexContext)fn RdfLexer::find_transition(_self : RdfLexer, ctx : LexContext, char_class : CharClass) -> Transition?async fn[RR : GenMachine] ReaderIterator::next(self : ReaderIterator[RdfLexer, RR]) -> Result[RdfOut, LexerError]?pub(all) enum SerializationError {
FormatError(String)
IoError(String)
}impl Show for SerializationErrorfn[TR : TokenRecognizer, RR : GenMachine] SliceIterator::next(self : SliceIterator[TR, RR]) -> Result[RdfOut, LexerError]?impl Show for SourceRangepub(all) enum SubtagType {
PrivateUseIntro
ExtensionIntro(Char)
Alphabetic(Int)
Numeric(Int)
Alphanumeric(Int)
Invalid
}pub(all) enum TermRef {
NamedNodeRef(NamedNodeRef)
BlankNodeRef(BlankNodeRef)
LiteralRef(LiteralRef)
TripleRef(TripleRef)
} derive(Eq, Hash, Debug)pub(all) struct Transition {
from : LexStateMachine
char_class : CharClass
to : LexStateMachine
action : LexAction
priority : Int
} derive(Eq, Hash, Debug)impl Show for Transitionfn Transition::Transition(from : LexStateMachine, char_class : CharClass, to : LexStateMachine, action : LexAction, priority? : Int) -> Transitionfn Triple::from_terms(subject : NamedOrBlankNode, predicate : NamedNode, object : Term) -> Result[Triple, TryFromTermError]pub struct TripleRef {
subject : NamedOrBlankNodeRef
predicate : NamedNodeRef
object : TermRef
} derive(Eq, Hash, Debug)fn TripleRef::TripleRef(subject : NamedOrBlankNodeRef, predicate : NamedNodeRef, object : TermRef) -> TripleReffn[W] WriterNQuadsSerializer::serialize_quad(self : WriterNQuadsSerializer[W], q : Quad) -> Result[String, Unit]fn[W] WriterNTriplesSerializer::serialize_triple(self : WriterNTriplesSerializer[W], t : Triple) -> Result[String, Unit]fn find_newline_in_range(bytes : BytesView, start : Int, end : Int) -> Int?Install
Download zipMoonTTL is a high-performance RDF parsing and serialization library for MoonBit.