Guest User

Untitled

a guest
Dec 15th, 2018
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.71 KB | None | 0 0
  1. {-# Language TemplateHaskell, QuasiQuotes, FlexibleContexts #-}
  2. module Main where
  3.  
  4. import Text.Peggy hiding ( Expr, parse )
  5. import Text.Peggy.LeftRec
  6. import Prelude
  7.  
  8. type Id = String
  9.  
  10. data Prog = Prog Id [Decl] Stmt deriving (Show)
  11. data Lit = IntL Integer | StrL String deriving (Show)
  12. data Decl = VarD Id Id deriving (Show)
  13. data Stmt = AssignS Id Expr | IfS Expr Stmt (Maybe Stmt) | SubS [Stmt] deriving (Show)
  14. data Expr = AppE Expr Op Expr | LitE Lit | VarE Id deriving (Show)
  15. data Op = Add | Sub | Mul | Div | Eqv deriving (Show)
  16.  
  17. genParser [] $ removeLeftRecursion [peggy|
  18.  
  19. regionComment :: () =
  20. '(*' (regionComment / !'*)' . {()})* '*)' {()}
  21.  
  22. nm :: Id = [a-z_] [a-zA-Z0-9_]* { $1 : $2 }
  23. ty :: Id = nm
  24.  
  25. strLit :: Lit = ( '\"' (!'\"' .)* '\"'
  26. / '\'' (!'\'' .)* '\'') { StrL $1 }
  27. intLit :: Lit = [0-9]+ { IntL (read $1) }
  28.  
  29. stmt :: Stmt
  30. = "if" expr "then" stmt ("else" stmt)? { IfS $1 $2 $3 }
  31. / "begin" (stmt ";")* "end" { SubS $1 }
  32. / nm ":=" expr { AssignS $1 $2 }
  33.  
  34. op :: Op = "+" { Add } / "-" { Sub }
  35. / "*" { Mul } / "/" { Div } / "=" { Eqv }
  36.  
  37. expr :: Expr
  38. = expr op expr { AppE $1 $2 $3 }
  39. / "(" expr ")" { $1 }
  40. / lit:(strLit / intLit) { LitE lit }
  41. / nm { VarE $1 }
  42.  
  43. program :: Prog
  44. = "program" nm ";"
  45. ("var" nm ("," nm)* ":" ty ";" { ($1 : $2, $3) })*
  46. stmt
  47. { Prog $1
  48. (concatMap (\(vs,t) -> map (VarD t) vs) $2)
  49. $3
  50. }
  51. |]
  52.  
  53. parse code = parseString program "" code
  54. check code = either (const True) (const False) code
  55.  
  56. main = print . parse =<< getContents
  57.  
  58. test = print $ parse
  59. "program rrr; \
  60. \var y, lala : integer; \
  61. \begin \
  62. \ if y = 0 then begin \
  63. \ c := \"Hey?\"+10*20; \
  64. \ end \
  65. \ else begin \
  66. \ c := 'Hoe!' / (30-20); \
  67. \ end; \
  68. \ c := 60; \
  69. \end."
  70. -- >
  71. {-
  72. Right (Prog "rrr" [VarD "integer" "y",VarD "integer" "lala"]
  73. (SubS [IfS (AppE (VarE "y") Eqv (LitE (IntL 0)))
  74. (SubS [AssignS "c" (AppE (LitE (StrL "Hey?")) Add
  75. (AppE (LitE (IntL 10)) Mul (LitE (IntL 20))))])
  76. (Just (SubS [AssignS "c" (AppE (LitE (StrL "Hoe!")) Div
  77. (AppE (LitE (IntL 30)) Sub (LitE (IntL 20))))]))
  78. , AssignS "c" (LitE (IntL 60))
  79. ]))
Add Comment
Please, Sign In to add comment