Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[parser] enh: allow whitespace in Format specification #4060

Merged
merged 5 commits into from
May 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 22 additions & 21 deletions src/lfortran/parser/tokenizer.re
Original file line number Diff line number Diff line change
Expand Up @@ -753,31 +753,32 @@ void lex_format(unsigned char *&cur, Location &loc,
re2c:yyfill:enable = 0;
re2c:define:YYCTYPE = "unsigned char";

int = digit+;
int = digit (whitespace? digit)*;
dot_int = '.' whitespace? int;
E_int = 'E' whitespace? int;
data_edit_desc
= 'I' int ('.' int)?
| 'B' int ('.' int)?
| 'O' int ('.' int)?
| 'Z' int ('.' int)?
| 'F' int '.' int
| 'E' int '.' int ('E' int)?
| 'EN' int '.' int ('E' int)?
| 'ES' int '.' int ('E' int)?
| 'EX' int '.' int ('E' int)?
| 'G' int ('.' int ('E' int)?)?
| 'L' int
| 'A' (int)?
| 'D' int '.' int
| 'PE' int '.' int
| 'PF' int '.' int
= 'I' whitespace? int whitespace? dot_int?
| 'B' whitespace? int whitespace? dot_int?
| 'O' whitespace? int whitespace? dot_int?
| 'Z' whitespace? int whitespace? dot_int?
| 'F' whitespace? int whitespace? dot_int
| 'E' whitespace? int whitespace? dot_int whitespace? E_int?
| 'E' whitespace? 'N' whitespace? int whitespace? dot_int whitespace? E_int?
| 'E' whitespace? 'S' whitespace? int whitespace? dot_int whitespace? E_int?
| 'E' whitespace? 'X' whitespace? int whitespace? dot_int whitespace? E_int?
| 'G' whitespace? int whitespace? (dot_int whitespace? E_int?)?
| 'L' whitespace? int
| 'A' whitespace? (int)?
| 'D' whitespace? int whitespace? dot_int
| 'P' whitespace? 'E' whitespace? int whitespace? dot_int
| 'P' whitespace? 'F' whitespace? int whitespace? dot_int
| 'P'
| 'X'
;

position_edit_desc
= 'T' int
| 'TL' int
| 'TR' int
| int 'X'
= 'T' whitespace? int ('L' | 'R')? whitespace? int
| int whitespace? 'X'
;
control_edit_desc
= position_edit_desc
Expand Down Expand Up @@ -831,7 +832,7 @@ void lex_format(unsigned char *&cur, Location &loc,
'"' ('""'|[^"\x00])* '"' { continue; }
"'" ("''"|[^'\x00])* "'" { continue; }
'-' { continue; }
(int)? data_edit_desc { continue; }
(int)? whitespace? data_edit_desc { continue; }
control_edit_desc { continue; }
*/
}
Expand Down
192 changes: 136 additions & 56 deletions tests/format1.f90
Original file line number Diff line number Diff line change
@@ -1,60 +1,140 @@
program format_04
real :: a,b,c,d,e(6)
gxyd marked this conversation as resolved.
Show resolved Hide resolved
double precision :: r,s,t,real_hundred
real, parameter :: t1 = 3.47399991e-03, t2 = 3.47000011e-03
integer :: f,i,j
real(8) :: p,q
a = 123.456
b = 123.45678
c = 12.34
d = 123.45
f = 12345
i = 19
j = 21
r = 12345678
s = 23.5678
t = 0.345678
p = 2.0d0
q = 0.0d0
e = [-1.70138506e+38, -1.25381181e+38, 8.69779800e+37, &
-1.40706263e+37, 1.11501114e+37, -9.56332244e+37]
real_hundred = 100.0

real :: a,b,c,d,e(6)
double precision :: r,s,t,real_hundred
real, parameter :: t1 = 3.47399991e-03, t2 = 3.47000011e-03
integer :: f,i,j
real(8) :: p,q
a = 123.456
b = 123.45678
c = 12.34
d = 123.45
f = 12345
i = 19
j = 21
r = 12345678
s = 23.5678
t = 0.345678
p = 2.0d0
q = 0.0d0
e = [-1.70138506e+38, -1.25381181e+38, 8.69779800e+37, &
-1.40706263e+37, 1.11501114e+37, -9.56332244e+37]
real_hundred = 100.0

print *, "ok", "b"
print '(a,a)', "ok", "b"
print '("Success!",/,10X,A6,"World!")',"Hello 123"
print '(4a4)',"dancing","in","the","moonlight"
print '(A2,4(2X,A),I3)',"ab", "cdef", "ghi", "jkl","qwerty",12
print '(i3,i10.5,/i6.6,2x,i3)' , 123,456,12345,6789
print '(d10.2,d15.6,d010.2,2x,d7.2)', 123.456, -123.45678, 12.34, -123.45
print '(1pd10.2,2pd15.6,1pd010.2,2x,1pd9.2)', -a, b, -c, d
print '(-1pe10.2,-2pe15.6,1pe010.2,2x,1pe9.2)', -a, b, -c, d
print "(12(i3))", 1,2,3,4,5,6,7,8,9,10,11,12
print "(4(i3),' hello')", 1,2,3,4,5,6,7,8,9,10,11,12,13,14
print '(i0)', f, -f
print '(d0.0,1x,d0.1,1x,d0.2)',a,b,c
print '(d0.0,1x,d0.1,1x,d0.2)',-a,-b,-c
print '("Hello")'
print '( F13.3,1X,F9.6,1X, F0.2 )', r, s, t
print '( F13.3,1X,F9.6,1X, F0.2 )', -r, -s, -t
print '(1PE13.6)', p, q
print '(F30.25)', 12345e-25
print '("x:", F4.2, " y:", ES7.1)', 1.123, 4.456
print '("x:", ES10.2)', 0.999, 0.1
print '("x:", ES15.5)', 0.102212
print "(*(es15.5e2,1x))", e
! test for issue: https://github.com/lfortran/lfortran/issues/4001
print "(F10.3)", abs(t2-t1)
print "(F10.3)", t2-t1
print "(F0.6)", real_hundred

! test for issue: https://github.com/lfortran/lfortran/issues/4040
print "(2 (I3))", i, j
print "(2 (I 3))", i, j
print 9, i, i + 1, j + 1, i + 2, j + 2
! the below test also ensures that blank character
! isn't removed from ' Dates: '
9 FORMAT (I12, /, ' Dates: ', 2 (2I3, I5))
gxyd marked this conversation as resolved.
Show resolved Hide resolved
print *, "ok", "b"
print '(a,a)', "ok", "b"
print 1, "ok", "b"
1 FORMAT ( a, a )
print '("Success!",/,10X,A6,"World!")',"Hello 123"
print 2, "Hello 123"
2 FORMAT ("Success!",/,10 X,A 6,"World!")
print 3, "Hello 123"
3 FORMAT ("Success!",/,1 0 X , A 6,"World!")
print '(4a4)',"dancing","in","the","moonlight"
print 4,"dancing","in","the","moonlight"
4 FORMAT (4a4)
print 5,"dancing","in","the","moonlight"
5 FORMAT (4 a 4)
print '(A2,4(2X,A),I3)',"ab", "cdef", "ghi", "jkl","qwerty",12
print 6,"ab", "cdef", "ghi", "jkl","qwerty",12
6 FORMAT (A 2,4(2 X,A),I3)
print 7,"ab", "cdef", "ghi", "jkl","qwerty",12
7 FORMAT (A 2,4 ( 2 X, A),I 3)
print '(i3,i10.5,/i6.6,2x,i3)' , 123,456,12345,6789
print 8 , 123,456,12345,6789
8 FORMAT (i3,i10.5,/i6.6,2 x,i3)
print 9 , 123,456,12345,6789
9 FORMAT (i 3,i 10. 5,/i 6 .6, 2 x,i 3)
print '(d10.2,d15.6,d010.2,2x,d7.2)', 123.456, -123.45678, 12.34, -123.45
print 10, 123.456, -123.45678, 12.34, -123.45
10 FORMAT (d 10.2,d 15.6,d 010.2,2x,d 7.2)
print 11, 123.456, -123.45678, 12.34, -123.45
11 FORMAT (d 10 .2,d 1 5. 6, d 0 10.2, 2 x, d 7 .2)
print '(1pd10.2,2pd15.6,1pd010.2,2x,1pd9.2)', -a, b, -c, d
print 12, -a, b, -c, d
12 FORMAT (1p d10.2,2 p d15.6,1p d010. 2,2 x,1pd9.2)
print 13, -a, b, -c, d
13 FORMAT (1 p d 10.2,2 p d1 5.6,1p d 0 10. 2,2 x,1 p d 9.2)
print '(-1pe10.2,-2pe15.6,1pe010.2,2x,1pe9.2)', -a, b, -c, d
print 14, -a, b, -c, d
14 FORMAT (- 1 p e 10.2,-2 p e 15.6,1 p e 010 . 2, 2 x,1 pe 9.2)
print 15, -a, b, -c, d
15 FORMAT (- 1 p e 10.2,-2 p e 15. 6,1 p e 01 0 . 2, 2 x, 1 pe 9. 2)
print "(12(i3))", 1,2,3,4,5,6,7,8,9,10,11,12
print 16, 1,2,3,4,5,6,7,8,9,10,11,12
16 FORMAT ( 12 ( i 3 ))
print "(4(i3),' hello')", 1,2,3,4,5,6,7,8,9,10,11,12,13,14
print 17, 1,2,3,4,5,6,7,8,9,10,11,12,13,14
17 FORMAT (4 ( i 3),' hello')
print '(i0)', f, -f
print 18, f, -f
18 FORMAT (i0)
print '(d0.0,1x,d0.1,1x,d0.2)',a,b,c
print 19,a,b,c
19 FORMAT (d0. 0,1 x,d0.1,1x,d 0.2)
print 20, a, b, c
20 FORMAT (d 0. 0,1 x,d 0.1,1x, d 0.2)
print '(d0.0,1x,d0.1,1x,d0.2)',-a,-b,-c
print 21,-a,-b,-c
21 FORMAT (d 0.0,1x,d0.1,1x,d0.2)
print '("Hello")'
print '( F13.3,1X,F9.6,1X, F0.2 )', r, s, t
print 22, r, s, t
22 FORMAT ( F13.3,1 X,F9.6,1X, F0.2 )
print 23, r, s, t
23 FORMAT ( F 13.3,1 X,F 9.6,1 X, F 0. 2 )
print '( F13.3,1X,F9.6,1X, F0.2 )', -r, -s, -t
print 24, -r, -s, -t
24 FORMAT ( F 13.3,1X,F 9.6,1X, F0.2 )
print '(1PE13.6)', p, q
print 25, p, q
25 FORMAT (1PE13.6)
print '(F30.25)', 12345e-25
print 26, 12345e-25
26 FORMAT (F30.25)
print '("x:", F4.2, " y:", ES7.1)', 1.123, 4.456
print 27, 1.123, 4.456
27 FORMAT ("x:", F4.2, " y:", ES7.1)
print 28, 1.123, 4.456
28 FORMAT ("x:", F 4. 2, " y:", E S 7.1)
print '("x:", ES10.2)', 0.999, 0.1
print 29, 0.999, 0.1
29 FORMAT ("x:", E S 10.2)
print '("x:", ES15.5)', 0.102212
print 30, 0.102212
30 FORMAT ("x:", ES15.5)
print "(*(es15.5e2,1x))", e
print 31, e
31 FORMAT (*(es15.5e2,1x))
print 32, e
32 FORMAT (*( es 15. 5e2, 1 x))
! test for issue: https://github.com/lfortran/lfortran/issues/4001
print "(F10.3)", abs(t2-t1)
print 33, abs(t2-t1)
33 FORMAT (F10.3)
print "(F10.3)", t2-t1
print 34, t2-t1
34 FORMAT (F10.3)
print 35, t2-t1
35 FORMAT ( F 10. 3)
print "(F0.6)", real_hundred
print 36, real_hundred
36 FORMAT (F10.3)

! test for issue: https://github.com/lfortran/lfortran/issues/4040
print "(2 (I3))", i, j
print 37, i, j
37 FORMAT (I3)
print "(2 (I 3))", i, j
print 38, i, j
38 FORMAT (2 (I3))
! the below test also ensures that blank character
! isn't removed from ' Dates: '
print 39, i, i + 1, j + 1, i + 2, j + 2
39 FORMAT (I12, /, ' Dates: ', 2 (2I3, I5))
print 40, i, i + 1, j + 1, i + 2, j + 2
40 FORMAT (I 1 2, /, ' Dates: ', 2 ( 2 I 3, I 5 ))
print 41, i, i + 1, j + 1, i + 2, j + 2
41 FORMAT (I 12, /, ' Dates: ', 2 (2I3, I5))
print 42, i, i + 1, j + 1, i + 2, j + 2
42 FORMAT (I 1 2, /, ' Dates: ', 2 (2 I 3, I 5))
end program
4 changes: 2 additions & 2 deletions tests/reference/run-format1-04216cf.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"basename": "run-format1-04216cf",
"cmd": "lfortran --no-color {infile}",
"infile": "tests/format1.f90",
"infile_hash": "966241371d54babf05b96a103da9ba9e9dcd4528e988d1070bad904c",
"infile_hash": "d324625c99174885d784eb4d6a501a00f08dd087943ca62dfd804ae2",
"outfile": null,
"outfile_hash": null,
"stdout": "run-format1-04216cf.stdout",
"stdout_hash": "2d049a32e789e53edbd267ffd7102fa382d69b17107825b6375b5896",
"stdout_hash": "31478ffc296097dac344cb5569d524eb5835ccc856285157b187c52a",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
55 changes: 55 additions & 0 deletions tests/reference/run-format1-04216cf.stdout
Original file line number Diff line number Diff line change
@@ -1,38 +1,93 @@
okb
okb
okb
Success!
Hello World!
Success!
Hello World!
Success!
Hello World!
danc in themoon
danc in themoon
danc in themoon
ab cdef ghi jkl qwerty 12
ab cdef ghi jkl qwerty 12
ab cdef ghi jkl qwerty 12
123 00456
012345 ***
123 00456
012345 ***
123 00456
012345 ***
0.12D+03 -0.123457D+03 0.12D+02 *******
0.12D+03 -0.123457D+03 0.12D+02 *******
0.12D+03 -0.123457D+03 0.12D+02 *******
-1.23D+02 12.34568D+01 -1.23D+01 1.23D+02
-1.23D+02 12.34568D+01 -1.23D+01 1.23D+02
-1.23D+02 12.34568D+01 -1.23D+01 1.23D+02
-0.01E+04 0.001235E+05 -1.23E+01 1.23E+02
-0.01E+04 0.001235E+05 -1.23E+01 1.23E+02
-0.01E+04 0.001235E+05 -1.23E+01 1.23E+02
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 hello
5 6 7 8 hello
9 10 11 12 hello
13 14
1 2 3 4 hello
5 6 7 8 hello
9 10 11 12 hello
13 14
12345
-12345
12345
-12345
0.123456001D+3 0.1D+3 0.12D+2
0.123456001D+3 0.1D+3 0.12D+2
0.123456001D+3 0.1D+3 0.12D+2
-0.123456001D+3 -0.1D+3 -0.12D+2
-0.123456001D+3 -0.1D+3 -0.12D+2
Hello
12345678.000 23.567800 .35
12345678.000 23.567800 .35
12345678.000 23.567800 .35
-12345678.000 ********* -.35
-12345678.000 ********* -.35
2.000000E+00
0.000000E+00
2.000000E+00
0.000000E+00
0.0000000000000000000012345
0.0000000000000000000012345
x:1.12 y:4.5E+00
x:1.12 y:4.5E+00
x:1.12 y:4.5E+00
x: 9.99E-01
x: 1.00E-01
x: 9.99E-01
x: 1.00E-01
x: 1.02212E-01
x: 1.02212E-01
-1.70139E+38 -1.25381E+38 8.69780E+37 -1.40706E+37 1.11501E+37 -9.56332E+37
-1.70139E+38 -1.25381E+38 8.69780E+37 -1.40706E+37 1.11501E+37 -9.56332E+37
-1.70139E+38 -1.25381E+38 8.69780E+37 -1.40706E+37 1.11501E+37 -9.56332E+37
0.000
0.000
-0.000
-0.000
-0.000
100.000000
100.000
19 21
19
21
19 21
19 21
19
Dates: 20 22 21 23
19
Dates: 20 22 21 23
19
Dates: 20 22 21 23
19
Dates: 20 22 21 23
Loading