You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is an issue to contemplate a more flexible handling of LBNF rules in the backend. Currently there is a define pragma that allows rule names to be first-order functions over other rule names. However, this could be obsolete if we produced only an interface for abstract syntax (with a standard implementation) that could be implemented in different ways.
The interface would defined methods to construct abstract syntax and a view on abstract syntax for the pretty printer.
For example, consider the (ambiguous) LBNF grammar:
In Haskell, this could be represented by the following abstract syntax:
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
-- * Model classclassExpse|e->swhere-- FunctionalDependency neededeInt::Integer->eeMinus::e->e->eeStm::s->e->eclassStmsewhere--| s -> e where -- FunctionalDependency not neededsExp::e->ssWhile::e->s->s-- ** ViewclassViewExpsewhereviewE::e->ExpViewseclassViewStmsewhereviewS::s->StmViewsedataExpViewse=EIntInteger
| EMinusee
| EStmsedataStmViewse=SExpe
| SWhilees-- * Initial syntaxdataIExp=IEIntInteger
| IEMinusIExpIExp
| IEStmIStmIExpdataIStm=ISExpIExp
| ISWhileIExpIStm-- ** ConstructorsinstanceExpIStmIExpwhere
eInt =IEInt
eMinus =IEMinus
eStm =IEStminstanceStmIStmIExpwhere
sExp =ISExp
sWhile =ISWhile-- ** ViewsinstanceViewExpIStmIExpwhere
viewE =\caseIEInt i ->EInt i
IEMinus e e' ->EMinus e e'
IEStm s e ->EStm s e
instanceViewStmIStmIExpwhere
viewS =\caseISExp e ->SExp e
ISWhile e s ->SWhile e s
One could also make an instance that directly evaluates programs:
instance Exp () Integer where
eInt = id
eMinus = (-)
eStm _ = id
instance Stm () Integer where
sExp _ = ()
sWhile _ _ = ()
Basically, this is generating a standard interface to what are semantic actions of conventional parser generators.
allows to plug a custom implementation of parts of the abstract syntax, like the booleans of the host language for a type of booleans (see Bool production #231), or a different implementation of lists, etc.
allows any semantic actions in the parser (would need a monadic interface for effectful actions in Haskell)
Issue:
semantic actions are physically separated from grammar (in other file)
This can be an issue, but also an advantage, since the grammar can be studied by itself without being interleaved with the semantic actions. This is in the spirit of BNFC.
Disadvantage:
If one uses a custom implementation of AST and changes the grammar, one has to replay the changes on ones custom AST implementation. This is not an issue with define.
The text was updated successfully, but these errors were encountered:
Would this be an alternative to the GADT and functor implementations? Or would those become alternative default implementations under this design?
I presume this design will allow for position information, is that correct?
In terms of ease of use (edit: and/or error handling, printing, etc.) how do you think it compares with, say, using the current design and splitting the interpreter/compiler up into two parts:
A function that converts from AST to desired data structure/types.
Another that converts from that structure to…
(compiler) generated code, or
(interpreter) function taking input and producing output or actions
This is an issue to contemplate a more flexible handling of LBNF rules in the backend. Currently there is a
define
pragma that allows rule names to be first-order functions over other rule names. However, this could be obsolete if we produced only an interface for abstract syntax (with a standard implementation) that could be implemented in different ways.The interface would defined methods to construct abstract syntax and a view on abstract syntax for the pretty printer.
For example, consider the (ambiguous) LBNF grammar:
In Haskell, this could be represented by the following abstract syntax:
One could also make an instance that directly evaluates programs:
Basically, this is generating a standard interface to what are semantic actions of conventional parser generators.
Advantages:
define
(see also Some backends do not implement thedefine
pragma #266)Issue:
This can be an issue, but also an advantage, since the grammar can be studied by itself without being interleaved with the semantic actions. This is in the spirit of BNFC.
Disadvantage:
define
.The text was updated successfully, but these errors were encountered: