From 65bbc76238a60eaecbf1bdbbda65255794fff9f8 Mon Sep 17 00:00:00 2001 From: Joshua Roesslein Date: Mon, 15 Mar 2010 22:53:01 -0500 Subject: [PATCH] Major improvements and refactorings. --- examples/parse.ooc | 30 ++++++++++-- yaml/Common.ooc | 15 ------ yaml/Event.ooc | 67 +++++++-------------------- yaml/Parser.ooc | 80 ++++++++++++++++++++------------ yaml/libyaml.ooc | 113 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 205 insertions(+), 100 deletions(-) delete mode 100644 yaml/Common.ooc create mode 100644 yaml/libyaml.ooc diff --git a/examples/parse.ooc b/examples/parse.ooc index d30d237..5411175 100644 --- a/examples/parse.ooc +++ b/examples/parse.ooc @@ -1,9 +1,31 @@ use yaml import yaml/[Parser, Event] -main: func { - parser := EventParser new() - parser loadFromString("[1,2,3]") +MyParser: class extends YAMLParser { + init: func { + super() + setInputString("[1,2,3]") + } + + onStreamStart: func(event: StreamStartEvent) -> Bool { + "Stream starting" println() + return true + } + onStreamEnd: func(event: StreamEndEvent) -> Bool { + "Stream ending" println() + return true + } + onScalar: func(event: ScalarEvent) -> Bool { + "Scalar!" println() + return true + } + onSequenceStart: func(event: SequenceStartEvent) -> Bool { + "Sequence!" println() + return true + } +} - e := parser parse() +main: func { + parser := MyParser new() + parser parseAll() } diff --git a/yaml/Common.ooc b/yaml/Common.ooc deleted file mode 100644 index 1bf3c7c..0000000 --- a/yaml/Common.ooc +++ /dev/null @@ -1,15 +0,0 @@ -use yaml - -VersionDirective: cover from yaml_version_directive_t { - major: extern Int - minor: extern Int -} - -TagDirective: cover from yaml_tag_directive_t { - handle: extern UChar* - prefix: extern UChar* -} - -Mark: cover from yaml_mark_t { - index, line, column: extern SizeT -} diff --git a/yaml/Event.ooc b/yaml/Event.ooc index 98c259d..543c6f3 100644 --- a/yaml/Event.ooc +++ b/yaml/Event.ooc @@ -1,64 +1,29 @@ use yaml -import yaml/Common +import yaml/libyaml -Event: cover from struct yaml_event_s { - type: extern Int - data: extern EventData -} -EventType: cover { - STREAM_END: extern(YAML_STREAM_END_EVENT) static Int -} +Event: class { + event: _Event -EventData: cover { - startStream: extern(start_stream) StreamStartData - documentStart: extern(document_start) DocumentStartData - documentEnd: extern(document_end) DocumentEndData - alias: extern AliasData - scalar: extern ScalarData - sequenceStart: extern(sequence_start) SequenceStartData - mappingStart: extern(mapping_start) MappingStartData + type: func -> Int { event type } } -StreamStartData: cover { - encoding: extern Int -} +StreamStartEvent: class extends Event {} -DocumentStartData: cover { - versionDirective: extern(version_directive) VersionDirective* - tagDirectives: extern(tag_directives) TagDirectives - implicit: extern Int -} +StreamEndEvent: class extends Event {} -TagDirectives: cover { - start: extern TagDirective* - end: extern TagDirective* -} +DocumentStartEvent: class extends Event {} -DocumentEndData: cover { - implicit: extern Int -} +DocumentEndEvent: class extends Event {} -AliasData: cover { - anchor: extern UChar* -} +AliasEvent: class extends Event {} -ScalarData: cover { - anchor, tag, value: extern UChar* - length: extern SizeT - plainImplicit: extern(plain_implicit) Int - quotedImplicit: extern(quoted_implicit) Int - style: extern Int -} +ScalarEvent: class extends Event {} -SequenceStartData: cover { - anchor, tag: extern UChar* - implicit: extern Int - style: extern Int -} +SequenceStartEvent: class extends Event {} -MappingStartData: cover { - anchor, tag: extern UChar* - implicit: extern Int - style: extern Int -} +SequenceEndEvent: class extends Event {} + +MappingStartEvent: class extends Event {} + +MappingEndEvent: class extends Event {} diff --git a/yaml/Parser.ooc b/yaml/Parser.ooc index 488535f..52717e7 100644 --- a/yaml/Parser.ooc +++ b/yaml/Parser.ooc @@ -1,46 +1,66 @@ use yaml -import yaml/Event +import yaml/[libyaml, Event] -// LibYAML Parser covers & externs -include yaml -YamlParser: cover from yaml_parser_t -yaml_parser_initialize: extern func(...) -> Int -yaml_parser_delete: extern func(...) -yaml_parser_set_input_string: extern func(...) -yaml_parser_parse: extern func(...) -> Int +/** + A YAML streaming, event-driven parser. +*/ +YAMLParser: class { + parser: _Parser -BaseParser: abstract class { - parser: YamlParser - - init: func { - if(!yaml_parser_initialize(parser&)) { - Exception new("Failed to initialize parser") throw() - } + init: func ~base { + parser = _Parser new() } - __destroy__: func { - yaml_parser_delete(parser&) + setInputString: func(text: String) { + parser setInputString(text, text length()) } - loadFromString: func ~withLength(text: String, length: SizeT) { - yaml_parser_set_input_string(parser&, text as const UChar*, length) - } - loadFromString: func(text: String) { - loadFromString(text, text length()) + getNextEvent: func -> Event { + event := Event new() + parser parse(event event&) + return event } - parse: abstract func -> T -} + parseOne: func { + onEvent(getNextEvent()) + } -EventParser: class extends BaseParser { - event: Event + parseAll: func { + event: Event - parse: func -> T { - if(!yaml_parser_parse(parser&, event&)) { - Exception new("Error while parsing!") throw() + while(true) { + event = getNextEvent() + if(onEvent(event) == false || event type() == EventType STREAM_END) break } + } - return event + onEvent: func(event: Event) -> Bool { + match event type() { + case EventType STREAM_START => onStreamStart(event as StreamStartEvent) + case EventType STREAM_END => onStreamEnd(event as StreamEndEvent) + case EventType DOCUMENT_START => onDocumentStart(event as DocumentStartEvent) + case EventType DOCUMENT_END => onDocumentEnd(event as DocumentEndEvent) + case EventType ALIAS => onAlias(event as AliasEvent) + case EventType SCALAR => onScalar(event as ScalarEvent) + case EventType SEQUENCE_START => onSequenceStart(event as SequenceStartEvent) + case EventType SEQUENCE_END => onSequenceEnd(event as SequenceEndEvent) + case EventType MAPPING_START => onMappingStart(event as MappingStartEvent) + case EventType MAPPING_END => onMappingEnd(event as MappingEndEvent) + case => true + } } + + onStreamStart: func(event: StreamStartEvent) -> Bool { true } + onStreamEnd: func(event: StreamEndEvent) -> Bool { true } + onDocumentStart: func(event: DocumentStartEvent) -> Bool { true } + onDocumentEnd: func(event: DocumentEndEvent) -> Bool { true } + onAlias: func(event: AliasEvent) -> Bool { true } + onScalar: func(event: ScalarEvent) -> Bool { true } + onSequenceStart: func(event: SequenceStartEvent) -> Bool { true } + onSequenceEnd: func(event: SequenceEndEvent) -> Bool { true } + onMappingStart: func(event: MappingStartEvent) -> Bool { true } + onMappingEnd: func(event: MappingEndEvent) -> Bool { true } } + +YAMLError: class extends Exception {} diff --git a/yaml/libyaml.ooc b/yaml/libyaml.ooc new file mode 100644 index 0000000..7899470 --- /dev/null +++ b/yaml/libyaml.ooc @@ -0,0 +1,113 @@ +use yaml + +ParserStruct: cover from struct yaml_parser_s + +_Parser: cover from yaml_parser_t* { + new: static func -> This { + instance: This = gc_malloc(sizeof(ParserStruct)) + gc_register_finalizer(instance, __destroy__, instance, null, null) + if(!instance _init()) { + Exception new("Failed to initialize parser!") throw() + } + return instance + } + + __destroy__: func { + _delete() + } + + _init: extern(yaml_parser_initialize) func -> Int + _delete: extern(yaml_parser_delete) func + + setInputString: extern(yaml_parser_set_input_string) func(input: const UChar*, size: SizeT) + + parse: extern(yaml_parser_parse) func(event: _Event*) -> Int +} + +_Event: cover from struct yaml_event_s { + type: extern Int + data: extern EventData + + isEnd: func -> Bool { type == EventType STREAM_END } +} + +EventType: cover { + EMPTY: extern(YAML_NO_EVENT) static Int + STREAM_START: extern(YAML_STREAM_START_EVENT) static Int + STREAM_END: extern(YAML_STREAM_END_EVENT) static Int + DOCUMENT_START: extern(YAML_DOCUMENT_START_EVENT) static Int + DOCUMENT_END: extern(YAML_DOCUMENT_END_EVENT) static Int + ALIAS: extern(YAML_ALIAS_EVENT) static Int + SCALAR: extern(YAML_ALIAS_EVENT) static Int + SEQUENCE_START: extern(YAML_SEQUENCE_START_EVENT) static Int + SEQUENCE_END: extern(YAML_SEQUENCE_START_EVENT) static Int + MAPPING_START: extern(YAML_MAPPING_START_EVENT) static Int + MAPPING_END: extern(YAML_MAPPING_END_EVENT) static Int +} + +EventData: cover { + startStream: extern(start_stream) StreamStartData + documentStart: extern(document_start) DocumentStartData + documentEnd: extern(document_end) DocumentEndData + alias: extern AliasData + scalar: extern ScalarData + sequenceStart: extern(sequence_start) SequenceStartData + mappingStart: extern(mapping_start) MappingStartData +} + +StreamStartData: cover { + encoding: extern Int +} + +DocumentStartData: cover { + versionDirective: extern(version_directive) VersionDirective* + tagDirectives: extern(tag_directives) TagDirectives + implicit: extern Int +} + +DocumentEndData: cover { + implicit: extern Int +} + +AliasData: cover { + anchor: extern UChar* +} + +ScalarData: cover { + anchor, tag, value: extern UChar* + length: extern SizeT + plainImplicit: extern(plain_implicit) Int + quotedImplicit: extern(quoted_implicit) Int + style: extern Int +} + +SequenceStartData: cover { + anchor, tag: extern UChar* + implicit: extern Int + style: extern Int +} + +MappingStartData: cover { + anchor, tag: extern UChar* + implicit: extern Int + style: extern Int +} + +VersionDirective: cover from yaml_version_directive_t { + major: extern Int + minor: extern Int +} + +TagDirective: cover from yaml_tag_directive_t { + handle: extern UChar* + prefix: extern UChar* +} + +TagDirectives: cover { + start: extern TagDirective* + end: extern TagDirective* +} + +Mark: cover from yaml_mark_t { + index, line, column: extern SizeT +}