PROGRESS  master
prg_kernelparser_mod.F90
Go to the documentation of this file.
1 
5 
8 
9  implicit none
10 
11  private
12 
13  integer, parameter :: dp = kind(1.0d0)
14 
15  public :: prg_parsing_kernel
16 
17 contains
18 
27  subroutine prg_parsing_kernel(keyvector_char,valvector_char&
28  ,keyvector_int,valvector_int,keyvector_re,valvector_re,&
29  keyvector_log,valvector_log,filename,startstop)
30  implicit none
31  character(1), allocatable :: tempc(:)
32  character(100), allocatable :: vect(:,:)
33  character(50) :: keyvector_char(:), keyvector_int(:), keyvector_log(:), keyvector_re(:)
34  character(100) :: valvector_char(:)
35  character(len=*) :: filename
36  character(len=*), intent(in), optional :: startstop(2)
37  character(len=100) :: tempcflex
38  integer :: i, io_control, ios, j
39  integer :: k, l, lenc, nkey_char
40  integer :: nkey_int, nkey_log, nkey_re, readmaxi
41  integer :: readmaxj, readmini, valvector_int(:)
42  integer :: startatj, totalwords
43  logical :: start, stopl, valid, valvector_log(:), stopparsing, defaultnone
44  logical, allocatable :: checkmissing_char(:), checkmissing_int(:), checkmissing_log(:), checkmissing_re(:)
45  real(dp) :: valvector_re(:)
46 
47  readmaxi = 5 ; readmaxj = 1000
48  allocate(vect(readmaxi,readmaxj))
49  nkey_char = size(keyvector_char,dim=1)
50  nkey_re = size(keyvector_re,dim=1)
51  nkey_int = size(keyvector_int,dim=1)
52  nkey_log = size(keyvector_log,dim=1)
53 
54  call prg_open_file_to_read(io_control,filename)
55 
56  allocate(checkmissing_char(nkey_char),checkmissing_re(nkey_re), &
57  checkmissing_int(nkey_int), checkmissing_log(nkey_log))
58 
59  !Initialize the checkmissing flags and the vect array
60  checkmissing_char = .false.
61  checkmissing_re = .false.
62  checkmissing_int = .false.
63  checkmissing_log = .false.
64  stopparsing = .false.
65  defaultnone = .false.
66  vect = ' '
67 
68  do i=1,readmaxi !Here we read all the input into vect
69  read(io_control,*,iostat=ios)(vect(i,j),j=1,readmaxj)
70  end do
71 
72  close(io_control)
73 
74  !Look up for floating hashes (#)
75  totalwords = 0
76  do i=1,readmaxi
77  do k=1,readmaxj
78  if(adjustl(trim(vect(i,k))).ne."")totalwords = totalwords + 1
79  if(adjustl(trim(vect(i,k))).eq."#")then
80  write(*,*)" "
81  write(*,*)"ERROR in the the input file ..."
82  write(*,*)" "
83  write(*,*)"For this parsing routine everything is a comment by default unless theres an = sign"
84  write(*,*)"next to a word, in which case, it will be recognized as a keyword."
85  write(*,*)"This parser does not accept floating hashes (#). This is done in order to make sure"
86  write(*,*)"that a specific keyword is commented"
87  write(*,*)" "
88  write(*,*)"If you have a commented keyword make sure there is a # symbol right next to it"
89  write(*,*)" "
90  write(*,*)" The following commented keyword is correct: "
91  write(*,*)" #KeyWord= 1 "
92  write(*,*)" "
93  write(*,*)" The following commented keyword is NOT correct: "
94  write(*,*)" # KeyWord= 1 "
95  write(*,*)" "
96  stop
97  endif
98  if(adjustl(trim(vect(i,k))).eq."STOP{}")stopparsing = .true.
99  if(adjustl(trim(vect(i,k))).eq."DEFAULTNONE")defaultnone = .true.
100  enddo
101  enddo
102 
103  if(totalwords > readmaxi*readmaxj - 100) then
104  write(*,*)""; write(*,*)"Stopping ... Maximum allowed (keys + values + comments) words close to the limit "
105  write(*,*)"Increase the readmaxj variable in the prg_parsing_kernel subroutine or reduce the comments in the input"
106  stop
107  endif
108 
109  !Look up for boundaries
110  readmini=1
111  start=.false.
112  if(present(startstop))then
113  do i=1,readmaxi
114  do k=1,readmaxj
115  if(trim(vect(i,k)).eq.trim(startstop(1)))then
116  readmini=i
117  startatj=k
118  start=.true.
119  endif
120  if(start.and.trim(vect(i,k)).eq.trim(startstop(2)))then
121  readmaxi=i
122  endif
123  enddo
124  enddo
125  endif
126  write(*,*)startstop
127 
128  ! Look for invalid characters if startstop is present
129  if(start)then
130  start=.false.
131  stopl=.false.
132  do i=readmini,readmaxi
133  do k=1,readmaxj
134  if(trim(vect(i,k)).eq.trim(startstop(1)))start=.true.
135  valid = .false.
136  if(start)then
137  if(vect(i,k).ne.' ')then
138  do j=1,nkey_char
139  if(trim(vect(i,k)).eq.trim(keyvector_char(j)))then
140  valid = .true.
141  endif
142  enddo
143  do j=1,nkey_int
144  if(trim(vect(i,k)).eq.trim(keyvector_int(j)))then
145  valid = .true.
146  endif
147  enddo
148  do j=1,nkey_re
149  if(trim(vect(i,k)).eq.trim(keyvector_re(j)))then
150  valid = .true.
151  endif
152  enddo
153  do j=1,nkey_log
154  if(trim(vect(i,k)).eq.trim(keyvector_log(j)))then
155  valid = .true.
156  endif
157  enddo
158  if(trim(vect(i,k)).eq.trim(startstop(2)))then
159  stopl=.true.
160  endif
161  if(.not.valid.and..not.stopl)call prg_check_valid(vect(i,k))
162  endif
163  endif
164  enddo
165  enddo
166  endif
167 
168  stopl = .false.
169  do i=readmini,readmaxi !We search for the character keys
170  if(stopl)exit
171  do k=1,readmaxj
172  if(stopl)exit
173  if(vect(i,k).ne.' ')then
174  if(start)then !If we have a start key:
175  if(readmaxj*(i-1)+k .ge.readmaxj*(readmini-1)+startatj) then !If the position is beyond the start key:
176  if(trim(vect(i,k)).ne.'}')then !If we don't have a stop key:
177  do j=1,nkey_char
178  if(adjustl(trim(vect(i,k))).eq.adjustl(trim(keyvector_char(j))))then
179  valvector_char(j)=adjustl(trim(vect(i,k+1)))
180  checkmissing_char(j) = .true.
181  endif
182  end do
183  else
184  stopl = .true.
185  endif
186  endif
187  else !If we don't have a start key:
188  do j=1,nkey_char
189  if(trim(vect(i,k)).eq.trim(keyvector_char(j)))then
190  valvector_char(j)=trim(vect(i,k+1))
191  checkmissing_char(j) = .true.
192  endif
193  end do
194  endif
195  else
196  exit
197  end if
198  end do
199  end do
200 
201  stopl = .false.
202  do i=readmini,readmaxi !We search for the integer keys
203  if(stopl)exit
204  do k=1,readmaxj
205  if(stopl)exit
206  if(vect(i,k).ne.' ')then
207  if(start)then
208  if(readmaxj*(i-1)+k .ge.readmaxj*(readmini-1)+startatj) then
209  if(adjustl(trim(vect(i,k))).ne.'}')then
210  do j=1,nkey_int
211  if(trim(vect(i,k)).eq.trim(keyvector_int(j)))then
212  read(vect(i,k+1),*)valvector_int(j)
213  checkmissing_int(j) = .true.
214  end if
215  end do
216  else
217  stopl = .true.
218  endif
219  endif
220  else
221  do j=1,nkey_int
222  if(trim(vect(i,k)).eq.trim(keyvector_int(j)))then
223  read(vect(i,k+1),*)valvector_int(j)
224  checkmissing_int(j) = .true.
225  end if
226  end do
227  endif
228  else
229  exit
230  end if
231  end do
232  end do
233 
234  stopl = .false.
235  do i=readmini,readmaxi !We search for the real keys
236  if(stopl)exit
237  do k=1,readmaxj
238  if(stopl)exit
239  if(vect(i,k).ne.' ')then
240  if(start)then
241  if(readmaxj*(i-1)+k .ge.readmaxj*(readmini-1)+startatj) then
242  if(trim(vect(i,k)).ne.'}')then
243  do j=1,nkey_re
244  if(trim(vect(i,k)).eq.trim(keyvector_re(j)))then
245  read(vect(i,k+1),*)valvector_re(j)
246  checkmissing_re(j) = .true.
247  end if
248  end do
249  else
250  stopl = .true.
251  endif
252  endif
253  else
254  do j=1,nkey_re
255  if(trim(vect(i,k)).eq.trim(keyvector_re(j)))then
256  read(vect(i,k+1),*)valvector_re(j)
257  checkmissing_re(j) = .true.
258  end if
259  end do
260  endif
261  else
262  exit
263  end if
264  end do
265  end do
266 
267  stopl = .false.
268  do i=1,readmaxi !We search for the logical keys
269  if(stopl)exit
270  do k=1,readmaxj
271  if(stopl)exit
272  if(vect(i,k).ne.' ')then
273  if(start)then
274  if(readmaxj*(i-1)+k .ge.readmaxj*(readmini-1)+startatj) then
275  if(trim(vect(i,k)).ne.'}')then
276  do j=1,nkey_log
277  if(trim(vect(i,k)).eq.trim(keyvector_log(j)))then
278  read(vect(i,k+1),*)valvector_log(j)
279  checkmissing_log(j) = .true.
280  end if
281  end do
282  else
283  stopl = .true.
284  endif
285  endif
286  else
287  do j=1,nkey_log
288  if(trim(vect(i,k)).eq.trim(keyvector_log(j)))then
289  read(vect(i,k+1),*)valvector_log(j)
290  checkmissing_log(j) = .true.
291  end if
292  end do
293  endif
294  else
295  exit
296  end if
297  end do
298  end do
299 
300  !Check for missing keywords
301  write(*,*)' '
302  do i = 1,nkey_char
303  if(defaultnone .eqv..true.)then
304  if(checkmissing_char(i).neqv..true..and.trim(keyvector_char(i)).ne."DUMMY=")then
305  write(*,*)'ERROR: variable ',trim(keyvector_char(i)),&
306  ' is missing. Set this variable or remove the DEFAULTNONE keyword from the input file...'
307  write(*,*)'Default value is:',valvector_char(i)
308  stop
309  endif
310  endif
311  if(checkmissing_char(i).neqv..true.) write(*,*)'WARNING: variable ',trim(keyvector_char(i)),&
312  ' is missing. I will use a default value instead ...'
313  enddo
314  do i = 1,nkey_int
315  if(defaultnone .eqv..true.)then
316  if(checkmissing_int(i).neqv..true..and.trim(keyvector_int(i)).ne."DUMMY=")then
317  write(*,*)'ERROR: variable ',trim(keyvector_int(i)),&
318  ' is missing. Set this variable or remove the DEFAULTNONE keyword from the input file...'
319  write(*,*)'Default value is:',valvector_int(i)
320  stop
321  endif
322  endif
323  if(checkmissing_int(i).neqv..true.) write(*,*)'WARNING: variable ',trim(keyvector_int(i)),&
324  ' is missing. I will use a default value instead ...'
325  enddo
326  do i = 1,nkey_re
327  if(defaultnone .eqv..true.)then
328  if(checkmissing_re(i).neqv..true..and.trim(keyvector_re(i)).ne."DUMMY=")then
329  write(*,*)'ERROR: variable ',trim(keyvector_re(i)),&
330  ' is missing. Set this variable or remove the DEFAULTNONE keyword from the input file...'
331  write(*,*)'Default value is:',valvector_re(i)
332  stop
333  endif
334  endif
335  if(checkmissing_re(i).neqv..true.) write(*,*)'WARNING: variable ',trim(keyvector_re(i)),&
336  ' is missing. I will use a default value instead ...'
337  enddo
338  do i = 1,nkey_log
339  if(defaultnone .eqv..true.)then
340  if(checkmissing_log(i).neqv..true..and.trim(keyvector_log(i)).ne."DUMMY=")then
341  write(*,*)'ERROR: variable ',trim(keyvector_log(i)),&
342  ' is missing. Set this variable or remove the DEFAULTNONE keyword from the input file...'
343  write(*,*)'Default value is:',valvector_log(i)
344  stop
345  endif
346  endif
347  if(checkmissing_log(i).neqv..true.) write(*,*)'WARNING: variable ',trim(keyvector_log(i)),&
348  ' is missing. I will use a default value instead ...'
349  enddo
350  write(*,*)' '
351 
352  deallocate(checkmissing_char,checkmissing_re, checkmissing_int, checkmissing_log)
353 
354  ! Only rank 0 prints parameters
355  write(*,*)' '
356  if (printrank() .eq. 1) then
357 
358  write(*,*)"############### Parameters used for this run ################"
359  if(start)write(*,*)" ",startstop(1)
360  do j=1,nkey_int
361  write(*,*)" ",trim(keyvector_int(j)),valvector_int(j)
362  end do
363 
364  do j=1,nkey_re
365  write(*,*)" ",trim(keyvector_re(j)),valvector_re(j)
366  end do
367 
368  do j=1,nkey_char
369  write(*,*)" ",trim(keyvector_char(j)),valvector_char(j)
370  end do
371 
372  do j=1,nkey_log
373  write(*,*)" ",trim(keyvector_log(j)),valvector_log(j)
374  end do
375  if(start)write(*,*)" ",startstop(2)
376 
377  endif
378  write(*,*)' '
379 
380  if(stopparsing)then
381  write(*,*)"" ; write(*,*)"STOP key found. Stop parsing ... "; write(*,*)""
382  stop
383  endif
384 
385  deallocate(vect)
386 
387  end subroutine prg_parsing_kernel
388 
392  subroutine prg_check_valid(invalidc)
393  implicit none
394  character(1), allocatable :: tempc(:)
395  character(len=*), intent(in) :: invalidc
396  character(len=100) :: tempcflex
397  integer :: l, lenc
398 
399  lenc=len(adjustl(trim(invalidc)))
400  if(.not.allocated(tempc))allocate(tempc(lenc))
401  do l = 1,len(adjustl(trim(invalidc)))
402  tempcflex = adjustl(trim(invalidc))
403  tempc(l) = tempcflex(l:l)
404  if(tempc(l).eq."=".and.tempc(1).ne."#")then
405  write(*,*)"Input ERROR: ",adjustl(trim(invalidc))," is not a valid keyword"
406  stop
407  endif
408  enddo
409 
410  end subroutine prg_check_valid
411 
412 
413 end module prg_kernelparser_mod
Some general parsing functions.
subroutine prg_check_valid(invalidc)
Check for valid keywords (checks for an = sign)
subroutine, public prg_parsing_kernel(keyvector_char, valvector_char, keyvector_int, valvector_int, keyvector_re, valvector_re, keyvector_log, valvector_log, filename, startstop)
The general parsing function. It is used to vectorize a set of "keywords" "value" pairs as included i...
Module to handle input output files for the PROGRESS lib.
subroutine, public prg_open_file_to_read(io, name)
Opens a file to read.
The parallel module.
integer function, public printrank()