mirror of
https://github.com/sdiehl/write-you-a-haskell.git
synced 2024-08-16 15:11:06 +03:00
refine happy parser example
This commit is contained in:
parent
041b118c5d
commit
456dde3faa
@ -923,8 +923,8 @@ Resources
|
||||
---------
|
||||
|
||||
If any of these concepts are unfamiliar, there are some external resources that
|
||||
will try to explain them. The most thorough is probably the Stanford course
|
||||
lecture notes.
|
||||
will try to explain them. The most thorough is the Stanford course lecture
|
||||
notes.
|
||||
|
||||
* [Stanford CS240h](http://www.scs.stanford.edu/14sp-cs240h/) by Bryan O'Sullivan, David Terei
|
||||
* [Real World Haskell](http://www.amazon.com/Real-World-Haskell-Bryan-OSullivan/dp/05965149800) by Bryan O'Sullivan, Don Stewart, and John Goerzen
|
||||
|
@ -11,10 +11,10 @@ Extended Parser
|
||||
Up until now we've been using parser combinators to build our parsers. Parser
|
||||
combinators build top-down parsers that formally belong to the $\mathtt{LL}(k)$
|
||||
family of parsers. The parser proceeds top-down, with a sequence of $k$
|
||||
characters used to dispatch on the leftmost production rule.
|
||||
Combined with backtracking (i.e. the ``try``
|
||||
combinator) this is simultaneously both an extremely powerful and simple model
|
||||
to implement as we saw before with our simple 100 line parser library.
|
||||
characters used to dispatch on the leftmost production rule. Combined with
|
||||
backtracking (i.e. the ``try`` combinator) this is simultaneously both an
|
||||
extremely powerful and simple model to implement as we saw before with our
|
||||
simple 100 line parser library.
|
||||
|
||||
However there is a family of grammars that include left-recursion that
|
||||
$\mathtt{LL}(k)$ can be inefficient and often incapable of parsing.
|
||||
@ -49,15 +49,14 @@ tools.
|
||||
Toolchain
|
||||
---------
|
||||
|
||||
Our parser logic will be spread across two different modules.
|
||||
Our parser and lexer logic will be spread across two different modules.
|
||||
|
||||
* Lexer.x
|
||||
* Parser.y
|
||||
|
||||
The code in each of these modules is a hybrid of the specific Alex/Happy grammar
|
||||
syntax and arbitrary Haskell logic that is spliced in. Code delineated by braces
|
||||
(``{}``) is regular Haskell, while code outside is parser/lexer logic.
|
||||
|
||||
(``{}``) is regular Haskell, while code outside is parsera and lexer logic.
|
||||
|
||||
```haskell
|
||||
-- **Begin Haskell Syntax**
|
||||
@ -253,8 +252,8 @@ simple case we'll just add error handling with the ``Except`` monad.
|
||||
```
|
||||
|
||||
And finally our production rules, the toplevel entry point for our parser will
|
||||
be the ``expr`` rule. Notice how naturally we can write a left recursive grammar
|
||||
for our infix operators.
|
||||
be the ``expr`` rule. Notice how naturally we can write a left recursive
|
||||
grammar for our infix operators.
|
||||
|
||||
```haskell
|
||||
-- Entry point
|
||||
|
@ -95,7 +95,6 @@ In Haskell the convention for the sum and product notation is as follows:
|
||||
Recursive Types
|
||||
---------------
|
||||
|
||||
|
||||
```haskell
|
||||
roll :: Rec f -> f (Rec f)
|
||||
roll (Rec f) = f
|
||||
@ -158,7 +157,7 @@ int main()
|
||||
{
|
||||
Prod x = { .a = 1, .b = 2.0 };
|
||||
Sum sum1 = { .a = 1 };
|
||||
Sum sum2 = { .b = 1 };
|
||||
Sum sum2 = { .b = 2.0 };
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -12,5 +12,5 @@ int main()
|
||||
{
|
||||
Prod x = { .a = 1, .b = 2.0 };
|
||||
Sum sum1 = { .a = 1 };
|
||||
Sum sum2 = { .b = 1 };
|
||||
Sum sum2 = { .b = 2.0 };
|
||||
}
|
||||
|
19
chapter9/happy/LICENSE
Normal file
19
chapter9/happy/LICENSE
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2013-2015, Stephen Diehl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
31
chapter9/happy/README.md
Normal file
31
chapter9/happy/README.md
Normal file
@ -0,0 +1,31 @@
|
||||
Happy
|
||||
=====
|
||||
|
||||
A simple example use of the Happy/Alex toolchain to generate parsers.
|
||||
|
||||
To compile and run:
|
||||
|
||||
```shell
|
||||
$ cabal run
|
||||
```
|
||||
|
||||
Usage:
|
||||
|
||||
```ocaml
|
||||
Happy> 42
|
||||
[TokenNum 42]
|
||||
42
|
||||
|
||||
Happy> (\x -> x) 1
|
||||
[TokenLParen,TokenLambda,TokenSym "x",TokenArrow,TokenSym "x",TokenRParen,TokenNum 1]
|
||||
1
|
||||
|
||||
Happy> \x -> x*x*x*x*x - x + 1
|
||||
[TokenLambda,TokenSym "x",TokenArrow,TokenSym "x",TokenMul,TokenSym "x",TokenMul,TokenSym "x",TokenMul,TokenSym "x",TokenMul,TokenSym "x",TokenSub,TokenSym "x",TokenAdd,TokenNum 1]
|
||||
<<closure>>
|
||||
```
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
Released under MIT license.
|
@ -10,12 +10,12 @@ cabal-version: >=1.10
|
||||
|
||||
executable happyParser
|
||||
build-depends:
|
||||
base >= 4.6 && <4.7
|
||||
base >= 4.6 && <4.9
|
||||
, pretty >= 1.1 && <1.2
|
||||
, parsec >= 3.1 && <3.2
|
||||
, containers >= 0.5 && <0.6
|
||||
, containers >= 0.5 && <0.7
|
||||
, haskeline >= 0.7
|
||||
, mtl
|
||||
, mtl >= 2.2 && <2.4
|
||||
, transformers
|
||||
default-language: Haskell2010
|
||||
main-is: Main.hs
|
||||
@ -24,4 +24,6 @@ executable happyParser
|
||||
build-tools: alex, happy
|
||||
other-modules:
|
||||
Parser,
|
||||
Lexer
|
||||
Lexer,
|
||||
Syntax,
|
||||
Eval
|
6
chapter9/happy/stack.yaml
Normal file
6
chapter9/happy/stack.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
resolver: lts-3.16
|
||||
packages:
|
||||
- '.'
|
||||
extra-deps: []
|
||||
flags: {}
|
||||
extra-package-dbs: []
|
BIN
img/memory_layout.png
Normal file
BIN
img/memory_layout.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
@ -210,7 +210,7 @@ $if(title)$
|
||||
\noindent
|
||||
{\huge \textsf{Stephen Diehl}}
|
||||
\\
|
||||
\textsf{January 2015 (Draft)}
|
||||
\textsf{December 2015 (Draft)}
|
||||
|
||||
\end{titlepage}
|
||||
\pagecolor{white}
|
||||
|
Loading…
Reference in New Issue
Block a user