refine happy parser example

This commit is contained in:
Stephen Diehl 2015-12-13 13:58:00 -05:00
parent 041b118c5d
commit 456dde3faa
10 changed files with 75 additions and 19 deletions

View File

@ -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

View File

@ -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

View File

@ -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 };
}
```

View File

@ -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
View 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
View 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.

View File

@ -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

View File

@ -0,0 +1,6 @@
resolver: lts-3.16
packages:
- '.'
extra-deps: []
flags: {}
extra-package-dbs: []

BIN
img/memory_layout.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -210,7 +210,7 @@ $if(title)$
\noindent
{\huge \textsf{Stephen Diehl}}
\\
\textsf{January 2015 (Draft)}
\textsf{December 2015 (Draft)}
\end{titlepage}
\pagecolor{white}