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 (
"hello world", and booleans like
- 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.