edifact_parser 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []