1

I am creating a simple imperative language from scratch, I already have a working syntactic tree, without much complication, it just uses the bottom-up style of parsing to create it using a simple tree data structure. The idea now is to implement a complete LeBlanc-Cook style symbol table. Its structure is not complicated, the problem is that I don't know how to make happy fill it while creating the tree at the same time.

The idea behind doing it all in a single pass is that in this way the AST can be filled with only what is the minimum necessary, ignoring stuff like variable or type declarations, which only effects are in the symbol table. Traversing the AST to fill the table is my last option.

I have the basic idea of it being some kind of global state, modified just in certain select times, like when a new block is open or when a variable is declared, but I have no idea how to use the environment that happy gives me together with whatever monadic structure I would create.

I know this question could be reduced to something like "how does happy work?", but anyways. Any comment is appreciated.

Here's an example to illustrate a little better my question.

% monad {MyState}
...
START: INSTRUCTIONS   { (AST_Root $1, Final_Symtable_State) } -- Ideally

INSTRUCTIONS: INSTRUCTIONS INSTRUCTION    { $2:$1 } -- A list of all instructions
    | INSTRUCTION                         { [$1] }

INSTRUCTION : VARDEF    {%???}
    |  TYPEDEF
    |  VARMOD   
    | ...

...

VARDEF: let identifier : Int                   {%???}  -- This should modify the symtable state and not the tree
           | let identifier : Int = number     {%???}  -- This should modify the symtable and provide a new branch for the tree

It seems like a single state would maybe not work out, and there is a combination of monadic and not monadic actions, what would be the best structure to work this out.

Erick
  • 11
  • 2
  • For future readers: parsing in a custom monad is addressed in Section 2.5 of [the Happy manual](https://www.haskell.org/happy/doc/happy.pdf). It sounds like you've already read that, though, which leaves me a little unclear on what exactly you're asking. Is there a specific part of the manual you don't understand? – Benjamin Hodgson May 20 '18 at 23:03
  • It is more a question on the monads themselves, to be fair. I can already form an AST, without using any monads with happy, and, just building a sym-table seems easy enough just using a state and modifying after some select actions. The problem is doing both at the same time, I have no idea how to save an AST together with a symtable, and selectively modify one or the other when I want. – Erick May 20 '18 at 23:17
  • I'm not a Happy user, so don't listen to me too carefully, but from the docs it looks like Happy will basically immediately feed the monadic computation returned from the `{%}` block into `>>=`. So the value inside the monad (ie what you `return`) is what `$1`/`$2`/etc refer to in the parent production rule. Since it sounds like you only sometimes want there to be a value you'll probably need to return `Maybe` a node and filter it out in the parent. Just a sketch but hope that helps? – Benjamin Hodgson May 20 '18 at 23:22
  • Hmm, alright I think I see it slightly more clear, I did not get before that what happy did after an action was wrapping it in a return and passing it to the next with a bind. I will try something out. Thank you very much for answering!. – Erick May 20 '18 at 23:37

0 Answers0