@@ -8,11 +8,11 @@ discussed how to handle whitespace and comments.
88
99In some grammars whitespace and comments would not be considered significant and
1010so we might be tempted not to generate any tokens for them. However, in the
11−running example, we may want to make spaces significant. For example, we might
12−want to implement function application expressed by juxtaposition as in
13−Haskell and Idris like this: ``f x``.
11+running example, we may want to make spaces significant in the future. For
12+example, we might want to implement function application expressed by
13+juxtaposition as in Haskell and Idris like this: ``f x``.
1414
15−Also, I'm not sure if it is an problem for error messages and so on if some
15+Also, I'm not sure if it would be problem for error messages and so on if some
1616text does not have corresponding tokens.
1717
1818So, on this page, we will add a token for whitespace and comments.
@@ -85,42 +85,68 @@ Now that there are ``Comment`` tokens the parser needs to be able to handle them
8585So far we don't have any syntax that requires spaces to be significant so we
8686need to define the grammar so that it will parse with, or without, spaces.
8787This needs to be done in a systematic way, here I have defined the grammar so
88−that there is an optional space to the right of every atom or operator:
88+that there is an optional space to the right of every atom or operator.
89+First we add versions of ``intLiteral`` , ``openParen`` , ``closeParen``
90+and ``op`` that allow optional spaces/comments to the right of them:
8991
9092.. code-block:: idris
9193
92− partial
93− exprAtom : Rule Integer
94− exprAtom = (intLiteral <* commentSpace)
95− <|> intLiteral <|> (paren expr)
96−
97− partial
98− expr1 : Rule Integer
99− expr1 = map multInt exprAtom <*> (
100− (((op "*") <* commentSpace) <|> (op "*"))
101− *> exprAtom)
102−
103− partial
104− exprMult : Rule Integer
105− exprMult = expr1 <|> exprAtom
106−
107− partial
108− expr2 : Rule Integer
109− expr2 = map addInt exprMult <*> (
110− (((op "+") <* commentSpace) <|> (op "+"))
111− *> exprMult)
112−
113− partial
114− exprAdd : Rule Integer
115− exprAdd = expr2 <|> exprMult
116−
117− partial
118− expr3 : Rule Integer
119− expr3 = map subInt exprAdd <*> (
120− (((op "-") <* commentSpace) <|> (op "-"))
121− *> expr)
122−
123− expr = expr3 <|> exprAdd
94+ intLiteralC : Rule Integer
95+ intLiteralC = (intLiteral <* commentSpace) <|> intLiteral
96+
97+ openParenC : Rule Integer
98+ openParenC = (openParen <* commentSpace) <|> openParen
99+
100+ closeParenC : Rule Integer
101+ closeParenC = (closeParen <* commentSpace) <|> closeParen
102+
103+ ||| like op but followed by optional comment or space
104+ opC : String -> Rule Integer
105+ opC s = ((op s) <* commentSpace) <|> (op s)
106+
107+Then we just use these functions instead of the original functions:
108+
109+.. code-block:: idris
110+
111+ expr : Rule Integer
112+
113+ factor : Rule Integer
114+ factor = intLiteralC <|> do
115+ openParenC
116+ r <- expr
117+ closeParenC
118+ pure r
119+
120+ term : Rule Integer
121+ term = map multInt factor <*> (
122+ (opC "*")
123+ *> factor)
124+ <|> factor
125+
126+ expr = map addInt term <*> (
127+ (opC "+")
128+ *> term)
129+ <|> map subInt term <*> (
130+ (opC "-")
131+ *> term)
132+ <|> term
133+
134+ calc : String -> Either (ParseError (TokenData ExpressionToken))
135+ (Integer, List (TokenData ExpressionToken))
136+ calc s = parse expr (fst (lex expressionTokens s))
137+
138+ lft : (ParseError (TokenData ExpressionToken)) -> IO ()
139+ lft (Error s lst) = putStrLn ("error:"++s)
140+
141+ rht : (Integer, List (TokenData ExpressionToken)) -> IO ()
142+ rht i = putStrLn ("right " ++ (show i))
143+
144+ main : IO ()
145+ main = do
146+ putStr "alg>"
147+ x <- getLine
148+ either lft rht (calc x) -- eliminator for Either
149+
124150
125151Defining Block Structure using Indents
126152--------------------------------------