Advertisement
DanielDv99

Basic Parsec Parser

Apr 29th, 2021 (edited)
1,772
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module Parser where
  2.  
  3. import Text.ParserCombinators.Parsec
  4. import AccTree
  5.  
  6. type BasicProgram = [BasicLine]
  7.  
  8. data BasicLine = BasicLine
  9.     { lineNumber :: Integer
  10.     , command :: BasicCommand
  11.     } deriving (Show)
  12.  
  13. data BasicCommand
  14.     = BasicLet String BasicExpr
  15.     | BasicIf { condition :: BasicExpr, thenCmd :: BasicCommand, elseCmd :: Maybe BasicCommand }
  16.     | BasicPrint BasicExpr
  17.     deriving (Show)
  18.  
  19. data BasicExpr
  20.     = BinaryExpr BasicExpr BinOperator BasicExpr
  21.     | UnaryExpr BasicExpr UnaryOperator
  22.     | Var String
  23.     | Literal Int
  24.     deriving (Show)
  25.  
  26. type BinOperator = String
  27. type UnaryOperator = String
  28.  
  29. basicProgram :: GenParser Char st BasicProgram
  30. basicProgram = do
  31.     result <- many basicLine
  32.     ws
  33.     optional $ string "END"
  34.     eof
  35.     return result
  36.  
  37.  
  38. basicLine :: GenParser Char st BasicLine
  39. basicLine = do
  40.     lineNumber <- read <$> many1 digit
  41.     ws
  42.     command <- basicCommand
  43.     ws
  44.     return $ BasicLine lineNumber command
  45.  
  46. basicCommand :: GenParser Char st BasicCommand
  47. basicCommand = basicLet
  48.  
  49. basicLet :: GenParser Char st BasicCommand
  50. basicLet = do
  51.     optional $ string "LET" >> ws
  52.     id <- varName
  53.     ws; char '='; ws
  54.     expr <- expression
  55.  
  56.     return $ BasicLet id expr
  57.  
  58. varName :: GenParser Char st [Char]
  59. varName = do
  60.     firstChar <- choice [letter, char '_']
  61.     otherChars <- many (choice [alphaNum , char '_'])
  62.     return $ firstChar : otherChars
  63.  
  64. expression :: GenParser Char st BasicExpr
  65. expression
  66.     =   literal
  67.     <|> Var <$> varName
  68.  
  69. literal :: GenParser Char st BasicExpr
  70. literal = Literal . read <$> many1 digit
  71.  
  72. -- The end of line character is \n
  73. eol :: GenParser Char st Char
  74. eol = char '\n'
  75.  
  76. ws :: GenParser Char st ()
  77. ws = optional $ choice $ comment : map char [' ', '\t', '\n']
  78.  
  79. comment :: GenParser Char st Char
  80. comment = string "REM" >> many (noneOf ['\n']) >> eol
  81.  
  82. parseBasic :: String -> Either ParseError BasicProgram
  83. parseBasic = parse basicProgram ""
  84.  
  85. parseFile :: FilePath -> IO (Either ParseError BasicProgram)
  86. parseFile file = do
  87.     file <- readFile file
  88.     return $ parseBasic file
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement