fortio-namelist 1.0.0

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