PetitParser: Building composed (dependent) parsers and isolating productions code

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

PetitParser: Building composed (dependent) parsers and isolating productions code

Arturo Zambrano
Hi All,
 Could you please share some advice on the following situation?
 I wrote my first Petit Parser. 
 From the documentation I read that:
1) it is possible to depend on other parsers making the development more modular.
 2) The docs also suggest that, in order to separate grammars rules from productions, we can make a  parser with productions  a subclass of a parser which defines the grammar.

I started applying 1) so my structure is something like

  AbstractParser   " contains some common basic elements common to all subclasses)
       StatementAParser
       StatementBParser   
       PLParser  "this guy uses the StatementX parsers"

 So there is a parser for different statements of the programming language.
 The PLParser uses PetitParser dependency mechanism to rely on the Statement*Parsers.    For instance:
   PLParser>> ruleB
^ (self dependencyAt: StatementBParser)  ruleB


So far so good, the grammar is working, the parser works.

Now, I would like to write the productions, separately from the grammar part (remember 2) ), so I should make subclasses adding the productions in the form
  >>ruleA
   ^super ruleA  ===> [ my production code]

The point is that PLParser explicitly depends on Statements*Parser, and the name of the Statement*Parser appears here and there, so creating subclasses would result in maintenance nightmare. The new layer of parsers with productions will duplicate the dependencies and I foresee it will be a mess.

So now, I think that having just one big class with all the rules for the grammar is better if you plan to separate productions code  isolated from the grammar.

Am I right? Maybe I'm missing some point regarding writing composed parsers and separating productions from grammar.

Any pointer or comment is welcome.

Arturo




Reply | Threaded
Open this post in threaded view
|

Re: PetitParser: Building composed (dependent) parsers and isolating productions code

DiegoLont
Hi,

I have never used dependents (^ (self dependencyAt: StatementBParser)  ruleB), but here are my thoughts when reading this.

When parsing it makes sense to make a separation between syntax and semantics. Applying this functional distinction in your technical design usually makes sense. In practical terms making a class for the syntax (i.e. StatementASyntax) and one class for the semantics, subclassing the syntax (i.e. StatementASyntax subclass: StatementAParse).

So the question here is what class is responsible for the semantics and what class is responsible for the syntax. Depending on the answer on this question you should build your tree. Do you want your statement parsers to know the semantics of the statements as well, then I would suggest separate these in a syntax and a parser (and only having production rules in PLParser for rules that combine things and no production rules when the rule is merely forward them to your statement parser).

Or do the statement parsers merely do the syntax, and does the PLParser apply the semantics (maybe because the semantics is context sensitive), the you should not create a duplicate structure in your statement parsers, but have the production rules i the PLParser (or a subclass of PLParser).

As to your maintenance nightmare:
- I would add a superclass for the syntax, and not a subclass for the semantics.
- And maybe you should consider referring to the parser as a resource / factory method, so you only have one reference to each of your statement parsers.

PLParser>> ruleB
        ^ (self dependencyAt: self statementBParser) ruleB

PLParser>> statementBParser
        ^ StatementBParser

Regards,
Diego


> On 01 Feb 2018, at 14:42, Arturo Zambrano <[hidden email]> wrote:
>
> Hi All,
>  Could you please share some advice on the following situation?
>  I wrote my first Petit Parser.
>  From the documentation I read that:
> 1) it is possible to depend on other parsers making the development more modular.
>  2) The docs also suggest that, in order to separate grammars rules from productions, we can make a  parser with productions  a subclass of a parser which defines the grammar.
>
> I started applying 1) so my structure is something like
>
>   AbstractParser   " contains some common basic elements common to all subclasses)
>        StatementAParser
>        StatementBParser  
>        PLParser  "this guy uses the StatementX parsers"
>
>  So there is a parser for different statements of the programming language.
>  The PLParser uses PetitParser dependency mechanism to rely on the Statement*Parsers.    For instance:
>    PLParser>> ruleB
> ^ (self dependencyAt: StatementBParser)  ruleB
>
>
> So far so good, the grammar is working, the parser works.
>
> Now, I would like to write the productions, separately from the grammar part (remember 2) ), so I should make subclasses adding the productions in the form
>   >>ruleA
>    ^super ruleA  ===> [ my production code]
>
> The point is that PLParser explicitly depends on Statements*Parser, and the name of the Statement*Parser appears here and there, so creating subclasses would result in maintenance nightmare. The new layer of parsers with productions will duplicate the dependencies and I foresee it will be a mess.
>
> So now, I think that having just one big class with all the rules for the grammar is better if you plan to separate productions code  isolated from the grammar.
>
> Am I right? Maybe I'm missing some point regarding writing composed parsers and separating productions from grammar.
>
> Any pointer or comment is welcome.
>
> Arturo
>


Reply | Threaded
Open this post in threaded view
|

Re: PetitParser: Building composed (dependent) parsers and isolating productions code

Arturo Zambrano
Thanks Diego! I really appreciate your comments.

Best regards.
Arturo

On Fri, Feb 2, 2018 at 6:27 AM, Diego Lont <[hidden email]> wrote:
Hi,

I have never used dependents (^ (self dependencyAt: StatementBParser)  ruleB), but here are my thoughts when reading this.

When parsing it makes sense to make a separation between syntax and semantics. Applying this functional distinction in your technical design usually makes sense. In practical terms making a class for the syntax (i.e. StatementASyntax) and one class for the semantics, subclassing the syntax (i.e. StatementASyntax subclass: StatementAParse).

So the question here is what class is responsible for the semantics and what class is responsible for the syntax. Depending on the answer on this question you should build your tree. Do you want your statement parsers to know the semantics of the statements as well, then I would suggest separate these in a syntax and a parser (and only having production rules in PLParser for rules that combine things and no production rules when the rule is merely forward them to your statement parser).

Or do the statement parsers merely do the syntax, and does the PLParser apply the semantics (maybe because the semantics is context sensitive), the you should not create a duplicate structure in your statement parsers, but have the production rules i the PLParser (or a subclass of PLParser).

As to your maintenance nightmare:
- I would add a superclass for the syntax, and not a subclass for the semantics.
- And maybe you should consider referring to the parser as a resource / factory method, so you only have one reference to each of your statement parsers.

PLParser>> ruleB
        ^ (self dependencyAt: self statementBParser) ruleB

PLParser>> statementBParser
        ^ StatementBParser

Regards,
Diego


> On 01 Feb 2018, at 14:42, Arturo Zambrano <[hidden email]> wrote:
>
> Hi All,
>  Could you please share some advice on the following situation?
>  I wrote my first Petit Parser.
>  From the documentation I read that:
> 1) it is possible to depend on other parsers making the development more modular.
>  2) The docs also suggest that, in order to separate grammars rules from productions, we can make a  parser with productions  a subclass of a parser which defines the grammar.
>
> I started applying 1) so my structure is something like
>
>   AbstractParser   " contains some common basic elements common to all subclasses)
>        StatementAParser
>        StatementBParser
>        PLParser  "this guy uses the StatementX parsers"
>
>  So there is a parser for different statements of the programming language.
>  The PLParser uses PetitParser dependency mechanism to rely on the Statement*Parsers.    For instance:
>    PLParser>> ruleB
>       ^ (self dependencyAt: StatementBParser)  ruleB
>
>
> So far so good, the grammar is working, the parser works.
>
> Now, I would like to write the productions, separately from the grammar part (remember 2) ), so I should make subclasses adding the productions in the form
>   >>ruleA
>    ^super ruleA  ===> [ my production code]
>
> The point is that PLParser explicitly depends on Statements*Parser, and the name of the Statement*Parser appears here and there, so creating subclasses would result in maintenance nightmare. The new layer of parsers with productions will duplicate the dependencies and I foresee it will be a mess.
>
> So now, I think that having just one big class with all the rules for the grammar is better if you plan to separate productions code  isolated from the grammar.
>
> Am I right? Maybe I'm missing some point regarding writing composed parsers and separating productions from grammar.
>
> Any pointer or comment is welcome.
>
> Arturo
>