edifact_parser 0.9.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.
@@ -0,0 +1,20 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+
3
+ require 'edifact_parser/parser'
4
+ require 'edifact_parser/tokenizer'
5
+ require 'stringio'
6
+
7
+ module EdifactParser
8
+
9
+ def self.load_io(input)
10
+ tok = EdifactParser::Tokenizer.new input
11
+ parser = EdifactParser::Parser.new tok
12
+ handler = parser.parse
13
+ handler.result
14
+ end
15
+
16
+ def self.load(edi)
17
+ load_io(StringIO.new(edi))
18
+ end
19
+
20
+ end
@@ -0,0 +1,71 @@
1
+ module EdifactParser
2
+ class Handler
3
+ attr_reader :stack
4
+
5
+ def initialize
6
+ @stack = [[:array]]
7
+ @element_started = false
8
+ @empty = true
9
+ end
10
+
11
+ def start_segment
12
+ push [:array]
13
+ end
14
+
15
+ def start_element
16
+ push [:array]
17
+ @element_started = true
18
+ end
19
+
20
+ def scalar(s)
21
+ @stack.last << [:scalar, s]
22
+ @empty = false
23
+ end
24
+
25
+ def colon
26
+ if @empty
27
+ @stack.last << [:nil]
28
+ end
29
+ @empty = true
30
+ end
31
+
32
+ def end_segment
33
+ @stack.pop
34
+ end
35
+
36
+ def end_element
37
+ if @element_started
38
+ @stack.pop
39
+ @element_started = false
40
+ end
41
+ end
42
+
43
+ def qualifier(q)
44
+ @stack.last << [:scalar, q]
45
+ end
46
+
47
+ def result
48
+ root = @stack.first
49
+ process(root.first, root.drop(1))
50
+ end
51
+
52
+ private
53
+
54
+ def process(type, rest)
55
+ case type
56
+ when :array
57
+ rest.map { |x| process(x.first, x.drop(1)) }
58
+ when :scalar
59
+ rest.first
60
+ when :nil
61
+ nil
62
+ end
63
+ end
64
+
65
+ def push(o)
66
+ @stack.last << o
67
+ @stack << o
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,226 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by Racc 1.4.9
4
+ # from Racc grammer file "".
5
+ #
6
+
7
+ require 'racc/parser.rb'
8
+ module EdifactParser
9
+ class Parser < Racc::Parser
10
+
11
+
12
+ require_relative 'handler'
13
+
14
+ attr_reader :handler
15
+
16
+ def initialize(tokenizer, handler = Handler.new)
17
+ @tokenizer = tokenizer
18
+ @handler = handler
19
+ super()
20
+ end
21
+
22
+ def next_token
23
+ @tokenizer.next_token
24
+ end
25
+
26
+ def parse
27
+ do_parse
28
+ handler
29
+ end
30
+ ##### State transition tables begin ###
31
+
32
+ racc_action_table = [
33
+ 7, 27, 26, 4, 22, 17, 18, 17, 18, 27,
34
+ 26, 7, 7, 7, 8, 19 ]
35
+
36
+ racc_action_check = [
37
+ 0, 15, 15, 0, 11, 11, 11, 6, 6, 16,
38
+ 16, 3, 10, 2, 1, 8 ]
39
+
40
+ racc_action_pointer = [
41
+ -2, 14, 11, 9, nil, nil, 0, nil, 15, nil,
42
+ 10, -2, nil, nil, nil, -2, 6, nil, nil, nil,
43
+ nil, nil, nil, nil, nil, nil, nil, nil, nil ]
44
+
45
+ racc_action_default = [
46
+ -23, -23, -1, -23, -3, -5, -23, -13, -23, -4,
47
+ -2, -23, -8, -9, -10, -11, -12, -20, -21, 29,
48
+ -6, -7, -22, -14, -16, -17, -18, -19, -15 ]
49
+
50
+ racc_goto_table = [
51
+ 9, 12, 2, 23, 28, 10, 21, 11, 9, 20,
52
+ 3, 1 ]
53
+
54
+ racc_goto_check = [
55
+ 4, 8, 2, 13, 13, 2, 8, 6, 4, 7,
56
+ 3, 1 ]
57
+
58
+ racc_goto_pointer = [
59
+ nil, 11, 2, 10, -2, nil, 1, -2, -5, nil,
60
+ nil, nil, nil, -12, nil, nil ]
61
+
62
+ racc_goto_default = [
63
+ nil, nil, nil, nil, 5, 6, nil, nil, nil, 13,
64
+ 14, 15, 16, nil, 24, 25 ]
65
+
66
+ racc_reduce_table = [
67
+ 0, 0, :racc_error,
68
+ 1, 10, :_reduce_none,
69
+ 2, 10, :_reduce_none,
70
+ 1, 12, :_reduce_none,
71
+ 2, 11, :_reduce_none,
72
+ 1, 11, :_reduce_none,
73
+ 3, 13, :_reduce_none,
74
+ 2, 15, :_reduce_none,
75
+ 1, 15, :_reduce_none,
76
+ 1, 17, :_reduce_none,
77
+ 1, 17, :_reduce_none,
78
+ 1, 17, :_reduce_none,
79
+ 1, 17, :_reduce_none,
80
+ 1, 14, :_reduce_13,
81
+ 2, 18, :_reduce_none,
82
+ 2, 19, :_reduce_none,
83
+ 1, 22, :_reduce_none,
84
+ 1, 22, :_reduce_none,
85
+ 1, 24, :_reduce_18,
86
+ 1, 23, :_reduce_19,
87
+ 1, 20, :_reduce_20,
88
+ 1, 21, :_reduce_21,
89
+ 1, 16, :_reduce_22 ]
90
+
91
+ racc_reduce_n = 23
92
+
93
+ racc_shift_n = 29
94
+
95
+ racc_token_table = {
96
+ false => 0,
97
+ :error => 1,
98
+ :QUALIFIER => 2,
99
+ :STRING => 3,
100
+ :NUMBER => 4,
101
+ :OPTIONAL_BEGIN => 5,
102
+ :SEGMENT_END => 6,
103
+ :PLUS => 7,
104
+ :COLON => 8 }
105
+
106
+ racc_nt_base = 9
107
+
108
+ racc_use_result_var = true
109
+
110
+ Racc_arg = [
111
+ racc_action_table,
112
+ racc_action_check,
113
+ racc_action_default,
114
+ racc_action_pointer,
115
+ racc_goto_table,
116
+ racc_goto_check,
117
+ racc_goto_default,
118
+ racc_goto_pointer,
119
+ racc_nt_base,
120
+ racc_reduce_table,
121
+ racc_token_table,
122
+ racc_shift_n,
123
+ racc_reduce_n,
124
+ racc_use_result_var ]
125
+
126
+ Racc_token_to_s_table = [
127
+ "$end",
128
+ "error",
129
+ "QUALIFIER",
130
+ "STRING",
131
+ "NUMBER",
132
+ "OPTIONAL_BEGIN",
133
+ "SEGMENT_END",
134
+ "PLUS",
135
+ "COLON",
136
+ "$start",
137
+ "document",
138
+ "segments",
139
+ "beginning",
140
+ "segment",
141
+ "qual",
142
+ "values",
143
+ "segment_end",
144
+ "value",
145
+ "p_scalar",
146
+ "c_scalar",
147
+ "plus",
148
+ "col",
149
+ "scalar",
150
+ "string",
151
+ "number" ]
152
+
153
+ Racc_debug_parser = true
154
+
155
+ ##### State transition tables end #####
156
+
157
+ # reduce 0 omitted
158
+
159
+ # reduce 1 omitted
160
+
161
+ # reduce 2 omitted
162
+
163
+ # reduce 3 omitted
164
+
165
+ # reduce 4 omitted
166
+
167
+ # reduce 5 omitted
168
+
169
+ # reduce 6 omitted
170
+
171
+ # reduce 7 omitted
172
+
173
+ # reduce 8 omitted
174
+
175
+ # reduce 9 omitted
176
+
177
+ # reduce 10 omitted
178
+
179
+ # reduce 11 omitted
180
+
181
+ # reduce 12 omitted
182
+
183
+ def _reduce_13(val, _values, result)
184
+ @handler.start_segment; @handler.qualifier val[0]
185
+ result
186
+ end
187
+
188
+ # reduce 14 omitted
189
+
190
+ # reduce 15 omitted
191
+
192
+ # reduce 16 omitted
193
+
194
+ # reduce 17 omitted
195
+
196
+ def _reduce_18(val, _values, result)
197
+ @handler.scalar val[0]
198
+ result
199
+ end
200
+
201
+ def _reduce_19(val, _values, result)
202
+ @handler.scalar val[0].gsub("?", "")
203
+ result
204
+ end
205
+
206
+ def _reduce_20(val, _values, result)
207
+ @handler.end_element; @handler.start_element
208
+ result
209
+ end
210
+
211
+ def _reduce_21(val, _values, result)
212
+ @handler.colon
213
+ result
214
+ end
215
+
216
+ def _reduce_22(val, _values, result)
217
+ @handler.end_element; @handler.end_segment
218
+ result
219
+ end
220
+
221
+ def _reduce_none(val, _values, result)
222
+ val[0]
223
+ end
224
+
225
+ end # class Parser
226
+ end # module EdifactParser
@@ -0,0 +1,180 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by Racc 1.4.9
4
+ # from Racc grammer file "".
5
+ #
6
+
7
+ require 'racc/parser.rb'
8
+ module EdifactParser
9
+ class Parser < Racc::Parser
10
+
11
+ module_eval(<<'...end parser.y/module_eval...', 'parser.y', 35)
12
+
13
+ require_relative 'handler'
14
+
15
+ attr_reader :handler
16
+
17
+ def initialize(tokenizer, handler = Handler.new)
18
+ @tokenizer = tokenizer
19
+ @handler = handler
20
+ super()
21
+ end
22
+
23
+ def next_token
24
+ @tokenizer.next_token
25
+ end
26
+
27
+ def parse
28
+ do_parse
29
+ handler
30
+ end
31
+ ...end parser.y/module_eval...
32
+ ##### State transition tables begin ###
33
+
34
+ racc_action_table = [
35
+ 6, 7, 14, 10, 11, 10, 11, 6, 4, 3 ]
36
+
37
+ racc_action_check = [
38
+ 8, 4, 8, 13, 13, 5, 5, 2, 1, 0 ]
39
+
40
+ racc_action_pointer = [
41
+ 7, 8, 1, nil, 1, 2, nil, nil, -6, nil,
42
+ nil, nil, nil, 0, nil, nil ]
43
+
44
+ racc_action_default = [
45
+ -10, -10, -10, -2, -10, -10, -7, 16, -10, -4,
46
+ -5, -6, -1, -10, -9, -3 ]
47
+
48
+ racc_goto_table = [
49
+ 9, 5, 8, 2, 12, 1, nil, 13, 15 ]
50
+
51
+ racc_goto_check = [
52
+ 6, 3, 4, 2, 5, 1, nil, 3, 6 ]
53
+
54
+ racc_goto_pointer = [
55
+ nil, 5, 3, -1, -3, -4, -5, nil ]
56
+
57
+ racc_goto_default = [
58
+ nil, nil, nil, nil, nil, nil, nil, nil ]
59
+
60
+ racc_reduce_table = [
61
+ 0, 0, :racc_error,
62
+ 4, 10, :_reduce_none,
63
+ 1, 11, :_reduce_2,
64
+ 3, 13, :_reduce_none,
65
+ 1, 13, :_reduce_none,
66
+ 1, 15, :_reduce_none,
67
+ 1, 15, :_reduce_6,
68
+ 1, 12, :_reduce_7,
69
+ 1, 16, :_reduce_8,
70
+ 1, 14, :_reduce_9 ]
71
+
72
+ racc_reduce_n = 10
73
+
74
+ racc_shift_n = 16
75
+
76
+ racc_token_table = {
77
+ false => 0,
78
+ :error => 1,
79
+ :QUALIFIER => 2,
80
+ :STRING => 3,
81
+ :NUMBER => 4,
82
+ :SPACE => 5,
83
+ "+" => 6,
84
+ ":" => 7,
85
+ "'" => 8 }
86
+
87
+ racc_nt_base = 9
88
+
89
+ racc_use_result_var = true
90
+
91
+ Racc_arg = [
92
+ racc_action_table,
93
+ racc_action_check,
94
+ racc_action_default,
95
+ racc_action_pointer,
96
+ racc_goto_table,
97
+ racc_goto_check,
98
+ racc_goto_default,
99
+ racc_goto_pointer,
100
+ racc_nt_base,
101
+ racc_reduce_table,
102
+ racc_token_table,
103
+ racc_shift_n,
104
+ racc_reduce_n,
105
+ racc_use_result_var ]
106
+
107
+ Racc_token_to_s_table = [
108
+ "$end",
109
+ "error",
110
+ "QUALIFIER",
111
+ "STRING",
112
+ "NUMBER",
113
+ "SPACE",
114
+ "\"+\"",
115
+ "\":\"",
116
+ "\"'\"",
117
+ "$start",
118
+ "segment",
119
+ "qual",
120
+ "plus",
121
+ "values",
122
+ "segment_end",
123
+ "value",
124
+ "colon" ]
125
+
126
+ Racc_debug_parser = false
127
+
128
+ ##### State transition tables end #####
129
+
130
+ # reduce 0 omitted
131
+
132
+ # reduce 1 omitted
133
+
134
+ module_eval(<<'.,.,', 'parser.y', 8)
135
+ def _reduce_2(val, _values, result)
136
+ raise "test"
137
+ result
138
+ end
139
+ .,.,
140
+
141
+ # reduce 3 omitted
142
+
143
+ # reduce 4 omitted
144
+
145
+ # reduce 5 omitted
146
+
147
+ module_eval(<<'.,.,', 'parser.y', 17)
148
+ def _reduce_6(val, _values, result)
149
+ @handler.scalar val[0]
150
+ result
151
+ end
152
+ .,.,
153
+
154
+ module_eval(<<'.,.,', 'parser.y', 21)
155
+ def _reduce_7(val, _values, result)
156
+ @handler.end_element; @handler.start_element; @handler.end_component; @handler.start_component
157
+ result
158
+ end
159
+ .,.,
160
+
161
+ module_eval(<<'.,.,', 'parser.y', 25)
162
+ def _reduce_8(val, _values, result)
163
+ @handler.end_component; @handler.start_component
164
+ result
165
+ end
166
+ .,.,
167
+
168
+ module_eval(<<'.,.,', 'parser.y', 29)
169
+ def _reduce_9(val, _values, result)
170
+ @handler.end_segment
171
+ result
172
+ end
173
+ .,.,
174
+
175
+ def _reduce_none(val, _values, result)
176
+ val[0]
177
+ end
178
+
179
+ end # class Parser
180
+ end # module EdifactParser
@@ -0,0 +1,42 @@
1
+ require 'strscan'
2
+
3
+ module EdifactParser
4
+ class Tokenizer
5
+ OPTIONAL_BEGIN = /^UNA:\+\.\?\s'/
6
+ QUALIFIER = /(^|(?<='))(UNB|UNH|BGM|DTM|PAI|ALI|IMD|FTX|LOC|GIS|DGS|GIR|RFF|MEA|QTY|MOA|RTE|NAD|DOC|CTA|COM|TAX|PCD|CUX|TDT|TSR|PII|TOD|PAC|EQD|SEL|ALC|RNG|INP|LIN|PRI|UNS|UNT|UNZ|CNT)/
7
+ STRING = /[A-Za-z0-9\s\.]*(\?')*[A-Za-z0-9\s\.]*(\?\+)*[A-Za-z0-9\s\.]*(\?:)*[A-Za-z0-9\s\.]*/
8
+ SPACE = /\s+/
9
+ NUMBER = /[0-9]+(?=[\+:'])/
10
+ LINE_BREAK = /\n/
11
+ SEGMENT_END = /(?<!\?)'/
12
+ PLUS = /(?<!\?)\+/
13
+ COLON = /(?<!\?)\:/
14
+
15
+ def initialize(io)
16
+ @ss = StringScanner.new io.read
17
+ end
18
+
19
+ def next_token
20
+ return if @ss.eos?
21
+
22
+ # ignore spaces and line breaks
23
+ @ss.scan(SPACE)
24
+ @ss.scan(LINE_BREAK)
25
+
26
+ return if @ss.eos?
27
+
28
+ case
29
+ when text = @ss.scan(OPTIONAL_BEGIN) then [:OPTIONAL_BEGIN, text]
30
+ when text = @ss.scan(QUALIFIER) then [:QUALIFIER, text]
31
+ when text = @ss.scan(SEGMENT_END) then [:SEGMENT_END, text]
32
+ when text = @ss.scan(PLUS) then [:PLUS, text]
33
+ when text = @ss.scan(COLON) then [:COLON, text]
34
+ when text = @ss.scan(NUMBER) then [:NUMBER, text.to_i]
35
+ when text = @ss.scan(STRING) then [:STRING, text]
36
+ else
37
+ x = @ss.getch
38
+ [x, x]
39
+ end
40
+ end
41
+ end
42
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: edifact_parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Paul Van de Vreede
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: racc
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.4'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.4'
30
+ description: EdifactParser is a simple parser that parses the EDIFACT structure into
31
+ a Ruy structure so that you can validate and convert the EDIFACT into any structure
32
+ you like.
33
+ email: paul@vdvreede.net
34
+ executables: []
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - lib/edifact_parser/handler.rb
39
+ - lib/edifact_parser/parser.rb
40
+ - lib/edifact_parser/parser.tab.rb
41
+ - lib/edifact_parser/tokenizer.rb
42
+ - lib/edifact_parser.rb
43
+ homepage: https://github.com/pvdvreede/edifact_parser
44
+ licenses: []
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 1.8.23
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Parser for converting EDIFACT documents into a Ruby array of hashes.
67
+ test_files: []