2017-09-20 8 views
0

現時点では、特定のタイプのログファイル用のパーサーを作成してHaskellを学びたいと思っています。haskell ReadP(<++)関数の問題

私は、次のsingleBlockパーサexecetue場合:

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時に、ファイルの変更、したがって、フロートISNということですもう構文解析されません。

私はインクリメントラインを変更した場合:

increment <- (munch PP.nonDigitOnLine >> munch PP.floatDot >> munch PP.nonDigitOnLine >> munch PP.floatDot)

[("","1"),("","2"),("","3"),("","4"),("2.500E-01","5")]

fiftステップが正しく解析されます。偏った選択肢を残し<++を使用して

increment <- (munch PP.nonDigitOnLine >> munch PP.floatDot >> munch PP.nonDigitOnLine >> munch PP.floatDot) <++ (munch PP.nonDigit >> munch PP.floatDot)

:最初の4つのステップは、このように私はこれにincrement lineを変えることができると思った、空の文字列を生成します。しかし、私の出力を変更しません:

[("","1"),("","2"),("","3"),("","4"),("2.500E-01","5")]

編集:

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

はあなたがこの上で実行されているサンプルファイルを含めることができます

isFloatDot = do s <- munch floatDot if null s then pfail else return s 

は、次のスニペットは、正しい出力を生成しますか? – Alec

答えて

1

わずか20分:

ログファイルが(LOADのINCREMENT行を中心に)このようなものです後で、私は質問をすることでうんざりすることが判明した。

問題は、munch関数が常に成功するため、解析された文字列がnullのときに失敗するヘルパー関数を提供する必要があることです。

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