bromlife 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15d41d66995405636a1ba18481d39f546cb3131260e9415601b57f9efba42510
4
- data.tar.gz: 100cde67bad24de79e6adb76b3b6090f88351853f49d30175ad7887e5347926e
3
+ metadata.gz: 2880bb24a47333a5ec7d44ed5d7e82ac8e1e924cb85cd41dfdf6b8964629d44b
4
+ data.tar.gz: bfdd977bd83af03898b5ecc4b55213e62e7ec81309044ba66d45e053dad348b8
5
5
  SHA512:
6
- metadata.gz: eff5b0aca2bb023585b3ddcfab2b75f76018dd84c217dd740bf4f8afe80db1236624da93033fb5252a310d03e079f646e2154272fe8e49b34e1256561d65b4e4
7
- data.tar.gz: 257232dfce6fdbc2f818bb4bb2b386437505350b3183838558bc557d5b683073984ca09633afef512a37c04f2f530ef0d884ff0e8c1c2016c598b35f4c850732
6
+ metadata.gz: ee3d465c11aefaf3911b7af9c93d2c82ef9ea6da4f557c45c5ec452ea23bcbcca89e7d856b6d0055b334489566e8f7cca90df70bf72b76746185a7a1ac861e88
7
+ data.tar.gz: 1ad39aa6d3e17aa24889dc3052f2fa141d16f592acbc951ca9937361a224717c0d3183d552c29036c1378e4955c9e578b34976f0628af77204183903c130ff57
@@ -17,8 +17,7 @@
17
17
 
18
18
  require "mkmf"
19
19
 
20
- have_library("bromlife")
21
- have_func("oml_to_json", "bromlife.h")
20
+ have_library("bromlife") or raise "no bromlife library"
22
21
 
23
22
  # Makes all symbols private by default to avoid unintended conflict
24
23
  # with other gems. To explicitly export symbols you can use RUBY_FUNC_EXPORTED
@@ -15,36 +15,31 @@
15
15
  */
16
16
 
17
17
  #include "rb_bromlife.h"
18
+
18
19
  #include <bromlife.h>
20
+
19
21
  #include <ruby.h>
22
+
20
23
  #include <stddef.h>
21
24
  #include <stdint.h>
22
25
 
23
- VALUE rb_mBromlife, rb_eError, rb_cParser, rb_cNodeIter, rb_cElement;
26
+ /* Prefix "rbb_" means RuBy Bromlife. */
24
27
 
25
- /**
26
- * call-seq:
27
- * oml_to_dumped_json (source) -> JSON String
28
- */
29
- static VALUE
30
- rb_oml_m_oml_to_dumped_json (VALUE self, VALUE source)
31
- {
32
- (void)self;
33
- char *bytes = rb_string_value_ptr (&source);
34
- long len = RSTRING_LEN (source);
35
- size_t json_len;
36
- uint8_t *json_bytes = oml_to_json ((uint8_t *)bytes, (size_t)len, &json_len);
37
- if (!json_bytes)
38
- rb_raise (rb_eError, "failed to convert to JSON");
39
- return rb_str_new ((char *)json_bytes, json_len);
40
- }
28
+ VALUE rb_mBromlife, rb_eError, rb_cParser;
41
29
 
42
30
  /* parser */
43
31
 
32
+ struct rbb_parser
33
+ {
34
+ struct oml_parser parser;
35
+ uint8_t *bytes;
36
+ };
37
+
44
38
  static void
45
39
  rb_oml_parser_free (void *parser)
46
40
  {
47
- oml_parser_free (parser);
41
+ struct rbb_parser *p = parser;
42
+ ruby_xfree (p);
48
43
  }
49
44
 
50
45
  static const rb_data_type_t rb_oml_parser_type
@@ -55,137 +50,66 @@ static const rb_data_type_t rb_oml_parser_type
55
50
  static VALUE
56
51
  rb_oml_parser_alloc (VALUE klass)
57
52
  {
58
- return TypedData_Wrap_Struct (klass, &rb_oml_parser_type, NULL);
53
+ return rb_data_typed_object_wrap (klass, NULL, &rb_oml_parser_type);
59
54
  }
60
55
 
61
56
  static VALUE
62
- rb_oml_parser_m_initialize (VALUE self)
57
+ rb_oml_parser_m_initialize (VALUE self, VALUE input)
63
58
  {
64
- OmlParser *parser = oml_parser_create ();
65
- if (!parser)
66
- rb_raise (rb_eError, "failed to create OML parser");
59
+ char *bytes = rb_string_value_ptr (&input);
60
+ size_t len = RSTRING_LEN (input);
61
+ struct rbb_parser *parser = ruby_xmalloc (sizeof (struct rbb_parser));
62
+ *parser = (struct rbb_parser){ .parser = oml_parser (bytes, len),
63
+ .bytes = bytes };
67
64
  RTYPEDDATA_DATA (self) = parser;
68
65
  return RUBY_Qnil;
69
66
  }
70
67
 
71
- /**
72
- * call-seq:
73
- * feed (String source)
74
- */
75
- static VALUE
76
- rb_oml_parser_m_feed (VALUE self, VALUE source)
68
+ static inline VALUE
69
+ rbb_raise (const char *message)
77
70
  {
78
- char *bytes = rb_string_value_ptr (&source);
79
- long len = RSTRING_LEN (source);
80
- if (!oml_parser_feed (RTYPEDDATA_DATA (self), (uint8_t *)bytes, len))
81
- rb_raise (rb_eError, "failed to feed to parser");
71
+ rb_raise (rb_eError, "%s", message);
82
72
  return RUBY_Qnil;
83
73
  }
84
74
 
85
- static const rb_data_type_t rb_oml_node_iter_type;
86
- /**
87
- * call-seq:
88
- * finish -> Bromlife::NodeIter
89
- */
90
- static VALUE
91
- rb_oml_parser_m_finish (VALUE self)
92
- {
93
- OmlNodeIter *iter = oml_parser_finish (RTYPEDDATA_DATA (self));
94
- if (!iter)
95
- rb_raise (rb_eError, "failed to finish parser");
96
- return TypedData_Wrap_Struct (rb_cNodeIter, &rb_oml_node_iter_type, iter);
97
- }
98
-
99
- /* node iterator */
100
-
101
- static void
102
- rb_oml_node_iter_free (void *iter)
103
- {
104
- oml_node_iter_free (iter);
105
- }
106
-
107
- static const rb_data_type_t rb_oml_node_iter_type
108
- = { .wrap_struct_name = "OML node iterator",
109
- .function = { .dfree = rb_oml_node_iter_free },
110
- .flags = RUBY_TYPED_FREE_IMMEDIATELY };
111
-
112
75
  static VALUE
113
- rb_oml_node_iter_alloc (VALUE klass)
76
+ rb_oml_parser_m_next (VALUE self)
114
77
  {
115
- return TypedData_Wrap_Struct (klass, &rb_oml_node_iter_type, NULL);
116
- }
117
-
118
- static const rb_data_type_t rb_oml_element_type;
119
- /**
120
- * call-seq:
121
- * next -> String or Bromlife::Element or nil
122
- */
123
- static VALUE
124
- rb_oml_node_iter_m_next (VALUE self)
125
- {
126
- const OmlNode *node = oml_node_iter_next (RTYPEDDATA_DATA (self));
127
- if (!node)
128
- return RUBY_Qnil;
129
- if (oml_node_is_element (node))
130
- {
131
- const OmlElement *element = oml_node_to_element (node);
132
- if (!element)
133
- rb_raise (rb_eError, "unreachable");
134
- return TypedData_Wrap_Struct (rb_cElement, &rb_oml_element_type,
135
- (void *)element);
136
- }
137
- else if (oml_node_is_text (node))
138
- {
139
- size_t len;
140
- const uint8_t *bytes = oml_node_to_text (node, &len);
141
- if (!bytes)
142
- rb_raise (rb_eError, "unreachable");
143
- return rb_str_new_static ((const char *)bytes, len);
144
- }
145
- else
146
- rb_raise (rb_eError, "unreachable");
147
- }
148
-
149
- /* element */
150
-
151
- /* Elements are managed by the root node iterator.
152
- */
153
- static const rb_data_type_t rb_oml_element_type
154
- = { .wrap_struct_name = "OML element",
155
- .function = { .dfree = NULL },
156
- .flags = RUBY_TYPED_FREE_IMMEDIATELY };
157
-
158
- static VALUE
159
- rb_oml_element_alloc (VALUE klass)
160
- {
161
- return TypedData_Wrap_Struct (klass, &rb_oml_element_type, NULL);
162
- }
163
-
164
- /**
165
- * call-seq:
166
- * label -> String
167
- */
168
- static VALUE
169
- rb_oml_element_m_label (VALUE self)
170
- {
171
- size_t len;
172
- const uint8_t *bytes = oml_element_get_label (RTYPEDDATA_DATA (self), &len);
173
- if (!bytes)
174
- rb_raise (rb_eError, "failed to get label");
175
- return rb_str_new_static ((const char *)bytes, len);
176
- }
177
-
178
- /**
179
- * call-seq:
180
- * children -> Bromlife::NodeIter
181
- */
182
- static VALUE
183
- rb_oml_element_m_children (VALUE self)
184
- {
185
- OmlNodeIter *iter = oml_element_get_children (RTYPEDDATA_DATA (self));
186
- if (!iter)
187
- rb_raise (rb_eError, "failed to get children");
188
- return TypedData_Wrap_Struct (rb_cNodeIter, &rb_oml_node_iter_type, iter);
78
+ struct rbb_parser *parser = rb_check_typeddata (self, &rb_oml_parser_type);
79
+ struct oml_event event = oml_next (&parser->parser);
80
+ if (oml_event_is_empty (event))
81
+ rb_raise (rb_eStopIteration, "no more event");
82
+
83
+ VALUE type = oml_event_is_null (event) ? rb_id2sym (rb_intern ("null"))
84
+ : oml_event_is_left (event) ? rb_id2sym (rb_intern ("left"))
85
+ : oml_event_is_right (event) ? rb_id2sym (rb_intern ("right"))
86
+ : oml_event_is_body (event) ? rb_id2sym (rb_intern ("body"))
87
+ : rbb_raise ("unreachable");
88
+ VALUE subtype
89
+ = oml_event_is_normal (event) ? rb_id2sym (rb_intern ("normal"))
90
+ : oml_event_is_ignored (event) ? rb_id2sym (rb_intern ("ignored"))
91
+ : oml_event_is_vocab (event) ? rb_id2sym (rb_intern ("vocab"))
92
+ : oml_event_is_word (event) ? rb_id2sym (rb_intern ("word"))
93
+ : oml_event_is_label (event) ? rb_id2sym (rb_intern ("label"))
94
+ : RUBY_Qnil;
95
+
96
+ size_t len = oml_event_len (event);
97
+ VALUE str
98
+ = len == 0
99
+ ? RUBY_Qnil
100
+ : rb_utf8_str_new (parser->bytes + oml_event_offset (event), len);
101
+
102
+ VALUE label = RUBY_Qnil;
103
+ if (oml_event_is_left (event) && oml_event_is_normal (event))
104
+ label = rb_utf8_str_new (parser->bytes + oml_event_label_offset (event),
105
+ oml_event_label_len (event));
106
+
107
+ VALUE ary = rb_ary_new ();
108
+ rb_ary_push (ary, type);
109
+ rb_ary_push (ary, subtype);
110
+ rb_ary_push (ary, str);
111
+ rb_ary_push (ary, label);
112
+ return ary;
189
113
  }
190
114
 
191
115
  RUBY_FUNC_EXPORTED void
@@ -196,23 +120,10 @@ Init_bromlife (void)
196
120
  rb_define_const (rb_mBromlife, "LIBBROMLIFE_VERSION",
197
121
  rb_int2num_inline (OML_VERSION));
198
122
 
199
- rb_define_module_function (rb_mBromlife, "oml_to_dumped_json",
200
- rb_oml_m_oml_to_dumped_json, 1);
201
-
202
123
  rb_cParser = rb_define_class_under (rb_mBromlife, "Parser", rb_cObject);
203
124
  rb_define_alloc_func (rb_cParser, rb_oml_parser_alloc);
204
- rb_define_method (rb_cParser, "initialize", rb_oml_parser_m_initialize, 0);
205
- rb_define_method (rb_cParser, "feed", rb_oml_parser_m_feed, 1);
206
- rb_define_method (rb_cParser, "finish", rb_oml_parser_m_finish, 0);
207
-
208
- rb_cElement = rb_define_class_under (rb_mBromlife, "Element", rb_cObject);
209
- rb_define_alloc_func (rb_cElement, rb_oml_element_alloc);
210
- rb_define_method (rb_cElement, "label", rb_oml_element_m_label, 0);
211
- rb_define_method (rb_cElement, "children", rb_oml_element_m_children, 0);
212
-
213
- rb_cNodeIter = rb_define_class_under (rb_mBromlife, "NodeIter", rb_cObject);
214
- rb_define_alloc_func (rb_cNodeIter, rb_oml_node_iter_alloc);
215
- rb_define_method (rb_cNodeIter, "next", rb_oml_node_iter_m_next, 0);
125
+ rb_define_method (rb_cParser, "initialize", rb_oml_parser_m_initialize, 1);
126
+ rb_define_method (rb_cParser, "next", rb_oml_parser_m_next, 0);
216
127
 
217
128
  rb_eError = rb_define_class_under (rb_mBromlife, "Error", rb_eStandardError);
218
129
  }
@@ -18,5 +18,5 @@
18
18
  #++
19
19
 
20
20
  module Bromlife
21
- VERSION = "0.1.0"
21
+ VERSION = "0.2.0"
22
22
  end
data/lib/bromlife.rb CHANGED
@@ -21,4 +21,56 @@ require_relative "bromlife/version"
21
21
  require "bromlife/bromlife"
22
22
 
23
23
  module Bromlife
24
+ def self.dom_parse(input)
25
+ parser = Parser.new(input)
26
+ result = []
27
+ current = result
28
+ loop do
29
+ event = parser.next
30
+ event => [type, subtype, str, label]
31
+ case [type, subtype]
32
+ in [:left, :vocab | :word | :label | :ignored] \
33
+ | [:right, :vocab | :word | :label | :ignored] \
34
+ | [:body, :label | :ignored] # nop
35
+ in [:body, :normal]
36
+ current << str
37
+ in [:left, :normal]
38
+ elem = Element.new(label:, parent: current)
39
+ current << elem
40
+ current = elem
41
+ in [:right, :normal]
42
+ current = current.parent
43
+ end
44
+ end
45
+ result
46
+ end
47
+
48
+ class Element
49
+ attr_reader :parent, :children
50
+ def initialize(label:, parent:)
51
+ @label = label
52
+ @parent = parent
53
+ @children = []
54
+ end
55
+
56
+ def <<(node)
57
+ @children << node
58
+ end
59
+
60
+ def deconstruct_keys(*_keys)
61
+ # TODO: optimize with keys param.
62
+ { label: @label, children: @children }
63
+ end
64
+
65
+ def inspect
66
+ "#<Bromlife::Element @label=#{ @label.inspect } @children=#{ @children.inspect }>"
67
+ end
68
+
69
+ def to_h
70
+ {
71
+ :label => @label,
72
+ :children => @children.map { |child| child.is_a?(String) ? child : child.to_h }
73
+ }
74
+ end
75
+ end
24
76
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bromlife
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - gemmaro
@@ -45,7 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
47
  requirements: []
48
- rubygems_version: 4.0.10
48
+ rubygems_version: 4.0.6
49
49
  specification_version: 4
50
50
  summary: O Markup Language parser library
51
51
  test_files: []