Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does mapDollarDollar belong in happy-grammar? #295

Closed
Ericson2314 opened this issue Sep 13, 2024 · 7 comments · Fixed by #307
Closed

Does mapDollarDollar belong in happy-grammar? #295

Ericson2314 opened this issue Sep 13, 2024 · 7 comments · Fixed by #307

Comments

@Ericson2314
Copy link
Collaborator

packages/backend-glr/src/Happy/Backend/GLR/ProduceCode.lhs:>   mkMatch tok = case mapDollarDollar tok of
packages/backend-glr/src/Happy/Backend/GLR/ProduceCode.lhs:>              in case mapDollarDollar tok of
packages/backend-glr/src/Happy/Backend/GLR/ProduceCode.lhs:>       Just p  -> case mapDollarDollar p of
packages/backend-lalr/src/Happy/Backend/LALR/ProduceCode.lhs:>         removeDollarDollar xs = case mapDollarDollar xs of
packages/backend-lalr/src/Happy/Backend/LALR/ProduceCode.lhs:>                     Just str' -> mapDollarDollar str'
packages/grammar/src/Happy/Grammar.lhs:>       mapDollarDollar
packages/grammar/src/Happy/Grammar.lhs:> mapDollarDollar :: String -> Maybe (String -> String)
packages/grammar/src/Happy/Grammar.lhs:> mapDollarDollar code0 = go code0 ""

it is just used in various backends. Unclear what the $$ is used for; untyped stuff to say the least.

@Ericson2314 Ericson2314 changed the title Does mapDollarDollar belong in happy-grammar Does mapDollarDollar belong in happy-grammar? Sep 13, 2024
@sgraf812
Copy link
Collaborator

sgraf812 commented Sep 15, 2024

$$ is described in the user's guide: https://haskell-happy.readthedocs.io/en/latest/using.html
It's part of the .y-files grammar, so it should be part of the Grammar AST data type.

I believe that you want a clearly defined interface to the happy-tabular middleend that works independently of the language of .y-files, something like the semantic essence of a grammar description. But Grammar is not that type, so you likely want to define your own domain layer that is independent of grammar-frontend. Perhaps Grammar can become that type, but then we still need an internal AST data type in grammar-frontend and a translation function that does not lose information.
That sounds like a non-trivial refactoring.

@Ericson2314
Copy link
Collaborator Author

Ericson2314 commented Sep 19, 2024

@sgraf812 Well nevermind Grammar, shouldn't that $$ be replaced with something in the abstract syntax (AbsSyn), before that is even turned into Grammar?

(It is also not clear to me that the $$ being changed with mapDollarDollar is the same one or not, but that could just be me not following the code.)

@sgraf812
Copy link
Collaborator

I suppose you could replace its use by its implementation. That is, whenever mapDollarDollar is called on some code block (presumably that code block defines a token), then pass down String -> String instead of String+mapDollarDollar. Sort of a higher-order abstract syntax encoding of the code block.

@Ericson2314
Copy link
Collaborator Author

If i understand correctly, if we parse the thing with $$ into a List String and then use intercalate, we should end up with the same result?

IMO first-order representation > higher-order representation > status quo.

@sgraf812
Copy link
Collaborator

sgraf812 commented Sep 20, 2024

You could think of the syntax

%token
      '='             { TokenEq }
      int             { TokenInt $$ }

describing a "pattern synonym" for happy actions. I.e.

foo : '=' int { putStrLn ("parsed an equals followed by an integer literal " ++ show $2) }

the use of int "matches" an integer literal TokenInt n, and that n is bound to $2 when executing the action associated to rule foo -> '=' int.

Likewise, other places in happy (OTOH I don't know which) will need to build an int, and will use \x -> TokenInt x to do so, based on the %token decl above.

I think it's far simpler to associate with each %token declaration its substitution action described by mapDollarDollar (which really should be called substDollarDollar). If we want to identify declarations that do not use $$, then we perhaps want the data type

data TokenDecl = Const String | Parameterised (String -> String)

instead. I don't think List String is a good idea; you will always want to substitute the same value for all occurrences of $$.

@Ericson2314
Copy link
Collaborator Author

I turns out that only the first $$ is treated specially. (I tested in the repl). Opening a PR in a second.

Ericson2314 added a commit to Ericson2314/happy that referenced this issue Sep 20, 2024
Instead of deferring the handling of `$$` to the backends, properly
parse the `$$` syntax up front, and store the result in the AST.

Note that the GLR backend was improperly substituting the `$$` twice.
Now that we have better types, this was surfaced as type error, and then
removed.

Fixes haskell#295
@sgraf812
Copy link
Collaborator

That rather sounds like a bug to me. But let's just preserve the status quo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants