on master help sign in
extend and fix parser library documentation
commit0ec3bdc56079e2b4e35f5f03546bb3544b00af97 authormartinbaker <git29f185@martinb.com> dateThu 16 Jan 2020, 13:44 (7 years ago) parenta99e963
2 files changed+70−44
docs/parserLibrary/introduction.rst+7−7 docs/parserLibrary/whitespace.rst+63−37
docs/parserLibrary/introduction.rst+7−7
@@ -25,21 +25,21 @@ complicated parser can be made out of many smaller ones.
2525 - Lexer - This takes the input string and turns it into a list of Tokens.
2626 - Parser - This takes the list of tokens and outputs the code.
2727
28−.. image:: ../image/parserTopLevel.png
29− :width: 307px
30− :height: 76px
31− :alt: diagram illustrating these stages of lexer and parser
28+ - .. image:: ../image/parserTopLevel.png
29+ :width: 307px
30+ :height: 76px
31+ :alt: diagram illustrating these stages of lexer and parser
3232
3333The advantage of using two stages, like this, is that things like whitespace and
3434comments don't need to be considered in every parser rule.
3535
36−The Idris parser library differs from Parsec in that you need to say in the
37−Recogniser whether a rule is guaranteed to consume input. This means that the
36+The Idris parser library differs from Parsec in that you need to say, in the
37+Recogniser, whether a rule is guaranteed to consume input. This means that the
3838Idris type system prevents the construction of recognisers/rules that can't
3939consume the input.
4040
4141The Lexer is similar but works at the level of characters rather than tokens, and
42−you need to provide a TokenMap which says how to build a token representation from
42+you need to provide a TokenMap which defines how to build a token from
4343a string when a rule is matched.
4444
4545The following pages contain a tutorial for the :ref:`parserLibraryLexer` and a
docs/parserLibrary/whitespace.rst+63−37
@@ -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--------------------------------------