Skip to content

Commit

Permalink
Postpone problem with ambiguity of actual parameters to semantic anal…
Browse files Browse the repository at this point in the history
…ysis
  • Loading branch information
linkrope committed Aug 14, 2024
1 parent 2412e11 commit eb678d0
Show file tree
Hide file tree
Showing 15 changed files with 278 additions and 289 deletions.
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
- we finish `gamma.input`
(handling of affix forms)
- we transform the gamma grammar model into the epsilon grammar model
(to reuse the compiler generation)
(to reuse the compiler generation)
- we remove the epsilon analyzer and move the lexer to `gamma.input.epsilang`

## Escape Sequences
Expand Down
2 changes: 1 addition & 1 deletion src/gamma/grammar/PrintingVisitor.d
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private class PrintingVisitor(Writer) : Visitor
this.writer.put(symbolNode.symbol.toString);
}

public void visit(Rule rule)
public void visit(Rule rule)
{
rule.alternatives.front.lhs.accept(this);
this.writer.put(" =");
Expand Down
41 changes: 41 additions & 0 deletions src/gamma/grammar/hyper/ActualParams.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module gamma.grammar.hyper.ActualParams;

import gamma.grammar.hyper.HyperVisitor;
import gamma.grammar.hyper.Operator;
import gamma.grammar.hyper.Params;
import gamma.grammar.Node;
import gamma.grammar.Visitor;
import gamma.util.Position;

/**
* This value object represents actual parameters on the right-hand side of a hyper rule.
*
* Note that for ident [ ActualParams ] [ ActualParams ] '(' (or '[' or '{')
* it is not obvious whether single ActualParams belong to ident or to '('.
* To keep the parser simple, this problem is postponed to semantic analysis.
*/
public class ActualParams : Node
{
private Params params_;

public this(Params params)
{
super(params.position);
this.params_ = params;
}

public override void accept(Visitor visitor)
{
accept(cast(HyperVisitor) visitor);
}

public void accept(HyperVisitor visitor)
{
visitor.visit(this);
}

public Params params()
{
return this.params_;
}
}
58 changes: 37 additions & 21 deletions src/gamma/grammar/hyper/EBNFConverter.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ module gamma.grammar.hyper.EBNFConverter;

import gamma.grammar.Alternative;
import gamma.grammar.Grammar;
import gamma.grammar.hyper.ActualParams;
import gamma.grammar.hyper.Group;
import gamma.grammar.hyper.HyperSymbolNode;
import gamma.grammar.hyper.HyperAlternative;
import gamma.grammar.hyper.HyperVisitor;
import gamma.grammar.hyper.Option;
import gamma.grammar.hyper.Repetition;
import gamma.grammar.hyper.RepetitionAlternative;
import gamma.grammar.Node;
import gamma.grammar.Nonterminal;
import gamma.grammar.Rule;
Expand Down Expand Up @@ -37,7 +37,7 @@ private class EBNFConverter : HyperVisitor

Nonterminal startSymbol;

SymbolNode[] lhsStack;
bool[] repetitionStack;

Node[][] rhsStack;

Expand All @@ -48,70 +48,86 @@ private class EBNFConverter : HyperVisitor
this.terminals = grammar.terminals;
this.alternatives = null;
this.startSymbol = grammar.startSymbol;

this.repetitionStack ~= false;
scope (exit)
this.repetitionStack.popBack;

grammar.rules.each!(rule => rule.accept(this));
}

void visit(HyperAlternative hyperAlternative)
{
visit(cast(Alternative) hyperAlternative);
}

void visit(Alternative alternative)
{
this.rhsStack ~= null;
scope (exit)
this.rhsStack.popBack;

alternative.rhs.each!(node => node.accept(this));
if (this.repetitionStack.back)
this.rhsStack.back ~= alternative.lhs;
this.alternatives ~= new Alternative(alternative.lhs, this.rhsStack.back, alternative.position);
this.rhsStack.popBack;
}

void visit(SymbolNode symbolNode)
{
this.rhsStack.back ~= symbolNode;
}

void visit(ActualParams)
{
// do nothing
}

void visit(Rule rule)
{
this.lhsStack ~= rule.lhs;
rule.alternatives.each!(alternative => alternative.accept(this));
this.lhsStack.popBack;
}

void visit(Group group)
{
this.repetitionStack ~= false;
scope (exit)
this.repetitionStack.popBack;

this.rhsStack.back ~= group.rule.lhs;
group.rule.accept(this);
}

void visit(Option option)
{
this.repetitionStack ~= false;
scope (exit)
this.repetitionStack.popBack;

this.rhsStack.back ~= option.rule.lhs;
option.rule.accept(this);

auto nonterminal = cast(Nonterminal) option.rule.lhs.symbol;
SymbolNode symbolNode = new HyperSymbolNode(nonterminal, option.endParams, option.position);
auto symbolNode = new SymbolNode(nonterminal, option.position);

this.alternatives ~= new Alternative(symbolNode, null, option.position);
}

void visit(Repetition repetition)
{
this.repetitionStack ~= true;
scope (exit)
this.repetitionStack.popBack;

this.rhsStack.back ~= repetition.rule.lhs;
repetition.rule.accept(this);

auto nonterminal = cast(Nonterminal) repetition.rule.lhs.symbol;
SymbolNode symbolNode = new HyperSymbolNode(nonterminal, repetition.endParams, repetition.position);
auto symbolNode = new SymbolNode(nonterminal, repetition.position);

this.alternatives ~= new Alternative(symbolNode, null, repetition.position);
}

void visit(RepetitionAlternative alternative)
{
this.rhsStack ~= null;
alternative.rhs.each!(node => node.accept(this));

auto nonterminal = cast(Nonterminal) this.lhsStack.back.symbol;
SymbolNode symbolNode = new HyperSymbolNode(nonterminal, alternative.params, alternative.position);
Node[] rhs = this.rhsStack.back ~ symbolNode;

this.alternatives ~= new Alternative(alternative.lhs, rhs, alternative.position);
this.rhsStack.popBack;
}

Grammar grammar()
{
import std.algorithm : filter;
Expand Down
5 changes: 2 additions & 3 deletions src/gamma/grammar/hyper/Group.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@ module gamma.grammar.hyper.Group;

import gamma.grammar.hyper.HyperVisitor;
import gamma.grammar.hyper.Operator;
import gamma.grammar.hyper.Params;
import gamma.grammar.Rule;
import gamma.util.Position;

public class Group : Operator
{
alias accept = Operator.accept;

public this(Params params, Rule rule, Position position)
public this(Rule rule, Position position)
{
super(params, rule, position);
super(rule, position);
}

public override void accept(HyperVisitor visitor)
Expand Down
21 changes: 14 additions & 7 deletions ...mma/grammar/hyper/RepetitionAlternative.d → src/gamma/grammar/hyper/HyperAlternative.d
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
module gamma.grammar.hyper.RepetitionAlternative;
module gamma.grammar.hyper.HyperAlternative;

import gamma.grammar.Alternative;
import gamma.grammar.hyper.HyperVisitor;
import gamma.grammar.hyper.Params;
import gamma.grammar.Node;
import gamma.grammar.Nonterminal;
import gamma.grammar.SymbolNode;
import gamma.grammar.Visitor;
import gamma.grammar.hyper.HyperVisitor;
import gamma.util.Position;

public class RepetitionAlternative : Alternative
public class HyperAlternative : Alternative
{
alias accept = Alternative.accept;

private Params params_;

public this(SymbolNode lhs, Node[] rhs, Params params, Position position)
private Node[] rhs_;

private Position position_;

public this(SymbolNode lhs, Params params, Node[] rhs, Position position)
in (cast(Nonterminal) lhs.symbol())
{
super(lhs, rhs, position);
this.params_ = params;
}

public override void accept(Visitor visitor)
public void accept(HyperVisitor visitor)
{
(cast(HyperVisitor) visitor).visit(this);
visitor.visit(this);
}

public Params params()
Expand Down
22 changes: 0 additions & 22 deletions src/gamma/grammar/hyper/HyperSymbolNode.d

This file was deleted.

9 changes: 6 additions & 3 deletions src/gamma/grammar/hyper/HyperVisitor.d
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
module gamma.grammar.hyper.HyperVisitor;

import gamma.grammar.hyper.ActualParams;
import gamma.grammar.hyper.Group;
import gamma.grammar.hyper.HyperAlternative;
import gamma.grammar.hyper.Option;
import gamma.grammar.hyper.Repetition;
import gamma.grammar.hyper.RepetitionAlternative;
import gamma.grammar.Visitor;

public interface HyperVisitor : Visitor
{
public void visit(HyperAlternative);

public void visit(ActualParams);

public void visit(Group);

public void visit(Option);

public void visit(Repetition);

public void visit(RepetitionAlternative);
}
11 changes: 1 addition & 10 deletions src/gamma/grammar/hyper/Operator.d
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
module gamma.grammar.hyper.Operator;

import gamma.grammar.hyper.HyperVisitor;
import gamma.grammar.hyper.Params;
import gamma.grammar.Node;
import gamma.grammar.Rule;
import gamma.grammar.Visitor;
import gamma.util.Position;

public abstract class Operator : Node
{
private Params params_;

private Rule rule_;

protected this(Params params, Rule rule, Position position)
protected this(Rule rule, Position position)
{
super(position);
this.params_ = params;
this.rule_ = rule;
}

Expand All @@ -27,11 +23,6 @@ public abstract class Operator : Node

public abstract void accept(HyperVisitor visitor);

public Params params()
{
return this.params_;
}

public Rule rule()
{
return this.rule_;
Expand Down
4 changes: 2 additions & 2 deletions src/gamma/grammar/hyper/Option.d
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ public class Option : Operator

private Params endParams_;

public this(Params params, Rule rule, Params endParams, Position position)
public this(Rule rule, Params endParams, Position position)
{
super(params, rule, position);
super(rule, position);
this.endParams_ = endParams;
}

Expand Down
2 changes: 1 addition & 1 deletion src/gamma/grammar/hyper/Params.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module gamma.grammar.hyper.Params;
import gamma.input.earley.AffixForm;
import gamma.util.Position;

// TODO: may gamma.grammar depend on gamma.input.earley?
// FXIME: gamma.grammar max not depend on gamma.input.earley
public class Params
{
private AffixForm[] affixForms_;
Expand Down
Loading

0 comments on commit eb678d0

Please sign in to comment.