fortio-namelist 1.0.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,325 @@
1
+ # ----------------------------------------------------------------------------
2
+ #
3
+ # fortran_namelist.y
4
+ #
5
+ # This file is part of simple-fortio library.
6
+ #
7
+ # Copyright (C) 2005-2021 Hiroki Motoyoshi
8
+ #
9
+ # ----------------------------------------------------------------------------
10
+
11
+ #
12
+ # racc fortran_namelist.y -> fortan_namelist.tab.rb
13
+ #
14
+
15
+ class FortIO::Namelist::Parser
16
+
17
+ prechigh
18
+ nonassoc COMMA
19
+ nonassoc NL
20
+ left ','
21
+ left '='
22
+ preclow
23
+
24
+ rule
25
+
26
+ namelist_all :
27
+ | namelist
28
+ | namelist namelist_all
29
+
30
+ namelist :
31
+ header tailer
32
+ { @root[val[0]] = []; @scan.in_namelist = nil }
33
+ | header paramlist tailer
34
+ { @root[val[0]] = val[1]; @scan.in_namelist = nil }
35
+
36
+ prefix : '&'
37
+ | '$'
38
+
39
+ header :
40
+ prefix IDENT { result = val[1].downcase; @scan.in_namelist = val[1].downcase }
41
+ | header NL
42
+
43
+ tailer :
44
+ '/'
45
+ | prefix IDENT { raise Racc::ParseError, "\nparse error (&)" unless val[1] =~ /\Aend\Z/i }
46
+
47
+ separator: COMMA
48
+ | NL
49
+
50
+ paramlist:
51
+ paramdef { result = [val[0]] }
52
+ | paramlist paramdef
53
+ { result = val[0] + [val[1]] }
54
+ | paramlist separator
55
+ { result = val[0] }
56
+
57
+ paramdef:
58
+ IDENT '=' separator
59
+ { result = ParamDef.new(val[0].downcase, nil, "") }
60
+ | IDENT '=' NIL
61
+ { result = ParamDef.new(val[0].downcase, nil, "") }
62
+ | IDENT '=' rvalues
63
+ { result = ParamDef.new(val[0].downcase, nil, val[2]) }
64
+ | IDENT '(' array_spec ')' '=' rvalues
65
+ { result = ParamDef.new(val[0].downcase, val[2], val[5]) }
66
+
67
+ rvalues :
68
+ abbreb { result = val[0] }
69
+ | rvalues abbreb
70
+ { result = val[0] + val[1] }
71
+ | rvalues ',' abbreb
72
+ { result = val[0] + val[2] }
73
+ | rvalues NL abbreb
74
+ { result = val[0] + val[2] }
75
+ | rvalues NIL
76
+ { result = val[0] + [nil] }
77
+ | NIL rvalues
78
+ { result = [nil] + val[1] }
79
+ | ',' rvalues
80
+ { result = [nil] + val[1] }
81
+ | rvalues NL
82
+ { result = val[0] }
83
+ | IDENT
84
+ { result = val[0] }
85
+
86
+ abbreb :
87
+ constant { result = [val[0]] }
88
+ | DIGITS '*' constant
89
+ { result = [val[2]] * val[0] }
90
+
91
+ constant :
92
+ STRING
93
+ | LOGICAL
94
+ | DIGITS
95
+ | FLOAT
96
+ | complex
97
+
98
+ real : DIGITS
99
+ | FLOAT
100
+
101
+ complex : '(' real ',' real ')' { result = Complex(val[1],val[3]) }
102
+
103
+ array_spec :
104
+ DIGITS { result = [val[0]-1] }
105
+ | DIGITS ':' DIGITS
106
+ { result = [(val[0]-1)..(val[2]-1)] }
107
+ | DIGITS ',' array_spec
108
+ { result = [val[0]-1] + val[2] }
109
+ | DIGITS ':' DIGITS ',' array_spec
110
+ { result = [(val[0]-1)..(val[2]-1)] + val[4] }
111
+
112
+ end
113
+
114
+ ---- inner
115
+
116
+ def parse (str)
117
+ @scan = FortIO::Namelist::Scanner.new(str)
118
+ @root = {}
119
+ begin
120
+ @yydebug = true
121
+ do_parse
122
+ rescue Racc::ParseError => err
123
+ message = ""
124
+ message << "namelist " << err.message[1..-1]
125
+ if @scan.in_namelist and @scan.in_namelist != "dummy"
126
+ message << " in &#{@scan.in_namelist} ... &end"
127
+ end
128
+ message << "\n"
129
+ message << @scan.debug_info
130
+ raise RuntimeError, message
131
+ end
132
+ return @root
133
+ end
134
+
135
+ def next_token
136
+ return @scan.yylex
137
+ end
138
+
139
+ ---- header
140
+
141
+ require "strscan"
142
+ require "stringio"
143
+
144
+ module FortIO
145
+ end
146
+
147
+ module FortIO::Namelist
148
+
149
+ class Scanner
150
+
151
+ def initialize (text)
152
+ @s = StringScanner.new(text)
153
+ @in_namelist = nil
154
+ end
155
+
156
+ attr_accessor :in_namelist
157
+
158
+ def debug_info
159
+ lines = @s.string.split(/\n/)
160
+ lineno = @s.string[0...@s.pos].split(/\n/).size
161
+ info = ""
162
+ if lineno > 1
163
+ info << format(" %4i: %s\n", lineno-1, lines[lineno-2])
164
+ end
165
+ info << format(">> %4i: %s\n", lineno, lines[lineno-1])
166
+ if lineno <= lines.size - 1
167
+ info << format(" %4i: %s\n", lineno+1, lines[lineno])
168
+ end
169
+ info
170
+ end
171
+
172
+ def yylex
173
+ while @s.rest?
174
+ unless @in_namelist
175
+ case
176
+ when @s.scan(/\A([\$&])/) ### {$|&}
177
+ @in_namelist = "dummy"
178
+ return [
179
+ @s[0],
180
+ nil
181
+ ]
182
+ when @s.scan(/\A[^\$&]/)
183
+ next
184
+ end
185
+ else
186
+ case
187
+ when @s.scan(/\A[+-]?(\d+)\.(\d+)?([ED][+-]?(\d+))?/i) ### float
188
+ return [ ### 1.2E+3, 1.E+3, 1.2E3
189
+ :FLOAT, ### 1.2, 1.
190
+ @s[0].sub(/D/i,'e').sub(/\.e/,".0e").to_f
191
+ ]
192
+ when @s.scan(/\A[+-]?\.(\d+)([ED][+-]?(\d+))?/i) ### float
193
+ return [ ### .2E+3, -.2E+3, .2E3
194
+ :FLOAT, ### .2, -.2
195
+ @s[0].sub(/D/i,'e').sub(/\./, '0.').to_f
196
+ ]
197
+ when @s.scan(/\A[+-]?(\d+)[ED][+-]?(\d+)/i) ### float
198
+ return [ ### 12E+3, 12E3, 0E0
199
+ :FLOAT,
200
+ @s[0].sub(/D/i,'e').to_f
201
+ ]
202
+ when @s.scan(/\A\d+[a-z_]\w*/i) ### STRING
203
+ return [
204
+ :STRING,
205
+ @s[0]
206
+ ]
207
+ when @s.scan(/\A[\-\+]?\d+/) ### digits
208
+ return [
209
+ :DIGITS,
210
+ Integer(@s[0])
211
+ ]
212
+ when @s.scan(/\A'((?:''|[^'])*)'/) ### 'quoted string'
213
+ return [
214
+ :STRING,
215
+ @s[1].gsub(/''/, "'")
216
+ ]
217
+ when @s.scan(/\A"((?:""|[^"])*)"/) ### 'double-quoted string'
218
+ return [
219
+ :STRING,
220
+ @s[1].gsub(/""/, '"')
221
+ ]
222
+ when @s.scan(/\A,/) ### ,
223
+ @s.scan(/\A[ \t]+/)
224
+ while @s.scan(/\A\n[ \t]*/) or @s.scan(/\A\![^\n]*/)
225
+ ### skip comment
226
+ end
227
+ if @s.scan(/\A\&[ \t]*\n[ \t]*\&/) ### & &
228
+ return [
229
+ ',',
230
+ nil
231
+ ]
232
+ elsif @s.match?(/\A[a-z]\w*/i) or @s.match?(/\A[\&\$\/\!]/)
233
+ return [
234
+ :COMMA,
235
+ nil
236
+ ]
237
+ elsif @s.match?(/\A,/)
238
+ return [
239
+ :NIL,
240
+ nil
241
+ ]
242
+ else
243
+ return [
244
+ ',',
245
+ nil
246
+ ]
247
+ end
248
+ when @s.scan(/\A\&[ \t]*\n[ \t]*\&/) ### & &
249
+ next
250
+ when @s.scan(/\A[\$&\/=\(\):*]/) ### {$|&|/|,|=|(|)|:|*}
251
+ return [
252
+ @s[0],
253
+ nil
254
+ ]
255
+ when @s.scan(/\A_\w*/i) ### STRING
256
+ return [
257
+ :STRING,
258
+ @s[0]
259
+ ]
260
+ when @s.scan(/\A\.t.*?\./i) ### LOGICAL true
261
+ return [
262
+ :LOGICAL,
263
+ true,
264
+ ]
265
+ when @s.scan(/\A\.f.*?\./i) ### LOGICAL false
266
+ return [
267
+ :LOGICAL,
268
+ false,
269
+ ]
270
+ when @s.match?(/\At[^\w]/i) ### LOGICAL true
271
+ @s.scan(/\At/i)
272
+ ms = @s[0]
273
+ if @s.match?(/\A[ \t]*=/)
274
+ return [
275
+ :IDENT,
276
+ ms
277
+ ]
278
+ else
279
+ return [
280
+ :LOGICAL,
281
+ true,
282
+ ]
283
+ end
284
+ when @s.match?(/\Af[^\w]/i) ### LOGICAL false
285
+ @s.scan(/\Af/i)
286
+ ms = @s[0]
287
+ if @s.match?(/\A[ \t]*=/)
288
+ return [
289
+ :IDENT,
290
+ ms
291
+ ]
292
+ else
293
+ return [
294
+ :LOGICAL,
295
+ false,
296
+ ]
297
+ end
298
+ when @s.scan(/\A[a-z]\w*/i) ### IDENT or LOGICAL
299
+ return [
300
+ :IDENT,
301
+ @s[0]
302
+ ]
303
+ when @s.scan(/\A\n/) ### newline
304
+ return [
305
+ :NL,
306
+ nil
307
+ ]
308
+ next
309
+ when @s.scan(/\A[ \t]+/) ### blank
310
+ next
311
+ when @s.scan(/\A![^\n]*?\n/) ### comment
312
+ next
313
+ else
314
+ @s.rest =~ /\A(.*)$/
315
+ raise "namelist parse error ('#{$1}')\n" + debug_info
316
+ end
317
+ end
318
+ end
319
+ end
320
+
321
+ end
322
+ end
323
+
324
+ ---- footer
325
+
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fortio-namelist
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Hiroki Motoyoshi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-02-22 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: " A library for reading/writing fortran namelist file\n"
14
+ email: ''
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - README.md
20
+ - Rakefile
21
+ - fortio-namelist.gemspec
22
+ - lib/fortio-namelist.rb
23
+ - lib/fortio-namelist/fortran_namelist.rb
24
+ - lib/fortio-namelist/fortran_namelist.tab.rb
25
+ - lib/fortio-namelist/fortran_namelist.y
26
+ homepage: https://github.com/himotoyoshi/fortio-namelist
27
+ licenses:
28
+ - MIT
29
+ metadata: {}
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: 1.8.1
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubygems_version: 3.1.2
46
+ signing_key:
47
+ specification_version: 4
48
+ summary: A library for reading/writing fortran namelist file
49
+ test_files: []