目前我正在尝试通过为某种类型的日志文件编写解析器来学习Haskell。
如果我执行以下singleBlock
解析器:
singleBlock :: ReadP (String, String)
singleBlock = do
st <- look
if "LOAD INCREMENT" `isInfixOf` st then do
fmap (head . splitOn "LOAD INCREMENT") look >>= string
increment <- (munch PP.nonDigit >> munch PP.floatDot)
fmap (head. splitOn "STEP") look >>= string
munch PP.nonDigit
step <- munch PP.digit
return (increment, step)
else pfail
它产生以下输出:
[("3.000E-01","1"),("3.000E-01","2"),("3.000E-01","3"),("1.000E-01","4"),("1","5")]
问题是,在第5步,文件发生了变化,因此Float不再被解析。
如果我将增量线更改为:
increment <- (munch PP.nonDigitOnLine >> munch PP.floatDot >> munch PP.nonDigitOnLine >> munch PP.floatDot)
[("","1"),("","2"),("","3"),("","4"),("2.500E-01","5")]
正确解析fift步骤。前4个步骤产生一个空字符串,因此我认为我可以将increment line
更改为:
increment <- (munch PP.nonDigitOnLine >> munch PP.floatDot >> munch PP.nonDigitOnLine >> munch PP.floatDot) <++ (munch PP.nonDigit >> munch PP.floatDot)
使用左侧偏向的<++
选项。然而,它并没有改变我的输出:
[("","1"),("","2"),("","3"),("","4"),("2.500E-01","5")]
编辑:
日志文件是这样的(关注LOAD INCREMENT行):
STEP 4 INITIATED:
LOAD INCREMENT: START STEPS * 1.000E-01
SPARSE: DIM=272114 NNZ(MAT)=19119044
SOLVE: REDUCTION RES= 0.14E-12 (INIT. RES= 0.96E+06) NI= 1
ETA-ENERGY DIAGRAM 0 0.000E+00 3.182E+02
ETA-ENERGY DIAGRAM 1 1.000E+00 2.344E+00
STEP 4 : DISPLACEMENT NORM = 3.851E-03 TOLERANCE = 1.000E-02
STEP 4 : FORCE NORM = 6.558E+05 TOLERANCE = 1.000E-02
RELATIVE OUT OF BALANCE FORCE = 2.708E-01 CHECK = FALSE
SPARSE: DIM=272114 NNZ(MAT)=19119044
SOLVE: REDUCTION RES= 0.44E-14 (INIT. RES= 0.18E+06) NI= 1
ETA-ENERGY DIAGRAM 0 0.000E+00 2.239E+00
ETA-ENERGY DIAGRAM 1 1.000E+00 1.464E+00
...
...
RELATIVE DISPLACEMENT VARIATION = 6.156E-03 CHECK = TRUE
RELATIVE OUT OF BALANCE FORCE = 1.722E-01 CHECK = FALSE
STEP 4 TERMINATED, CONVERGENCE AFTER 2 ITERATIONS
EXECUTION STOPPED ON TOTAL LOAD CRITERION
CONTINUED ANALYSIS POSSIBLE.
TOTAL LOAD FACTOR: LOADING(12) * 1.000E+00
PLASTICITY LOGGING SUMMARY
GROUP NAME PLAST, PRV. PL, CRITIC, PLAST NEW, PRV.PL NEW, CRITIC NEW
TOTAL MODEL 0 0 0 0 0 0
CRACKING LOGGING SUMMARY
GROUP NAME CRACK, OPEN, CLOSED, ACTIVE, INACTI, ARISES, RE-OPENS, CLOSES
TOTAL MODEL 698 698 0 694 4 209 0 0
CUMULATIVE REACTION: FORCE X FORCE Y FORCE Z
0.89594D-09 0.11246D+02 -0.67820D-08
STEP 5 INITIATED:
LOAD INCREMENT: LOADING( 1) * 2.500E-01
SPARSE: DIM=272114 NNZ(MAT)=19119044
SOLVE: REDUCTION RES= 0.53E-10 (INIT. RES= 0.11E+06) NI= 1
STEP 5 : ENERGY NORM = 7.379E+02 TOLERANCE = 1.000E-04
SPARSE: DIM=272114 NNZ(MAT)=19119044
SOLVE: REDUCTION RES= 0.56E-14 (INIT. RES= 0.11E+06) NI= 1
...
...
STEP 5 TERMINATED, CONVERGENCE AFTER 13 ITERATIONS
TOTAL LOAD FACTOR: LOADING( 1) * 2.500E-01
答案 0 :(得分:1)
仅仅20分钟后,事实证明我在问问题时很快乐。
问题是munch函数总是成功,因此我需要提供一个辅助函数,当解析后的字符串为null时它会失败。
isFloatDot = do
s <- munch floatDot
if null s then pfail
else return s
以下代码段会生成正确的输出:
singleBlock :: ReadP (String, String)
singleBlock = do
st <- look
if "LOAD INCREMENT" `isInfixOf` st then do
fmap (head . splitOn "LOAD INCREMENT") look >>= string
increment <- (munch PP.nonDigitOnLine >> munch PP.floatDot >> munch PP.nonDigitOnLine >> PP.isFloatDot) <++ (munch PP.nonDigit >> munch PP.floatDot)
fmap (head. splitOn "STEP") look >>= string
munch PP.nonDigit
step <- munch PP.digit
return (increment, step)
else pfail