
Okay guys, I finally did it and it turned out that Happy is actually
very easy to use .. only problem is that IMO documentation is not
great(or maybe I didn't pay enough attention reading it .. reading
docs is boring). Anyway, here's a short explanation(link for code is
also below):
Let's say you already wrote the lexer that returns `[TokPos]` where
data Token = ... your tokens ...
type TokPos = (Token, AlexPosn)
(AlexPosn contains location information)
and after telling Happy your token types, all you need to do is to
declare how tokens used in left-hand side of productions are matched
against tokens. Let's say I have this tokens:
data Token = A String | B Int | C
I'll need to add this token declarations in Happy file:
%token
a { (A $$, _) }
b { (B $$, _) }
c { (C, _) }
notice how I'm using ordinary pattern syntax. I didn't know this part
before. After that I can use a, b and c in left-hand side parts of
productions, like:
Exp : a b { SomeConstructor $1 $2 }
| c { SomeOtherConstructor }
and that's it. I hope that helps somebody.
Working code:
* Lexer(Alex): https://github.com/osa1/minCaml.hs/blob/master/src/Lexer.x
* Parser(Happy): https://github.com/osa1/minCaml.hs/blob/master/src/Parser.y
---
Ömer Sinan Ağacan
http://osa1.net
2014-03-09 18:45 GMT+02:00 Ömer Sinan Ağacan
Ha! I finally managed to use any kinds of tokens in Happy parsers ... Will post the code soon.
--- Ömer Sinan Ağacan http://osa1.net
2014-03-09 13:44 GMT+02:00 Mateusz Kowalczyk
: On 09/03/14 11:15, Ömer Sinan Ağacan wrote:
I think GHC uses alex+happy in very different way than explained in the docs.. For example it doesn't use "posn", "monadUserState" etc. wrappers as explained in alex documentations. I also can't figure out how does it keep track of token locations.. I guess It's just too complicated for me to understand without spending several hours.
--- Ömer Sinan Ağacan http://osa1.net
It doesn't use the wrappers provided, it instead uses its own data structures to do what the wrappers let you do and more. You can look for the data types defined in those modules to try and shed some light on how it's all done. I did mention it's not the most lightweight example ;)
-- Mateusz K.