Language2
More Parsing
module Main where
...
type Word = String
...
readLine :: String -> Nest
Parse either a single word or a nested brackets []. (We added more primitive parsers here.)
parseSingle :: Parser Nest
parseSingle = do
  spaces
  x <- (try parseFloat) <|>
       (try parseInt) <|>
       (try parseBool) <|>
       (try parseString) <|>
       (try parseWord) <|>
       (try parseNest)
  spaces
  return x
Parse a nested structure starting with [ and ending with ]
parseNest :: Parser Nest
parseInt :: Parser Nest
parseFloat :: Parser Nest
parseFloat = do
  I i <- parseInt
  char '.'
  I j <- parseInt
  res <- return $ (show i) ++ ['.'] ++ (show j)
  return $ W res       -- TODO: change W to what you defined for float.
Parse a simple word without any spaces or nesting between them.
parseWord :: Parser Nest
parseBool :: Parser Nest
parseBool = do
  b <- string "true" <|> string "false"
  return $ W (read b)       -- TODO: change W to what you defined for bool.
parseString :: Parser Nest
parseString = do
  char '''
  s <- many (noneOf "'")
  char '''
  return $ W s       -- TODO: change W to what you defined for string.
The tentative BNF notation for this language
A number is a sequence of digits
 | <digit>   ::= 0..9
 | <num>     ::= <digit>
 |             | <digit><num>
 | <letter>  ::= a..z | + | - | * | / | < | > | = | .
We define char to be either a letter or a number (non white space.)
 | <char>    ::= <letter>
 |             | <digit>
So that we can have words like dup2 that includes a number
 | <word>    ::= <letter>
 |             | <word> <char>
A nest is either a number or a word or an expression of the form [ .. ]
 | <nest>    ::= <num>
 |             | <word>
 |             | [ <nest>* ]
And of course our expression is just a list of nests
 | <expr>   ::= <nest>*
Can you define the data structure required for a larger abstract syntax?
Currently we have,
data Nest = W Word
          | I Int
          | Nested [Nest]
  deriving (Show)
This is somewhat limited, We should at least have a way to store real numbers (Float),
strings like "hello world", and booleans like true and false.
- Can you extend our data to add these things?
- Once you have done that, can you change the portions commented with TODO to use these instead? (Hint, you can use (read x) to convert x to any of int, bool or float from a string)
- What does the expression below give you if you execute on ghci after doing the above?
readLine  " 'hello world' 'hi' swap concat "
Remember, we are defining our abstract syntax here. So readLine now prints the abstract
syntax of the line being read.