Skip to content

Commit

Permalink
feature #343 : concrete syntax tree visitor
Browse files Browse the repository at this point in the history
  • Loading branch information
b3b00 committed Feb 21, 2023
1 parent 4f5a668 commit 77236f2
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 123 deletions.
10 changes: 9 additions & 1 deletion ParserTests/ExplicitTokensTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ private BuildResult<Parser<ExplicitTokensTokens, double>> BuildParser()
var parserInstance = new ExplicitTokensParser();
var builder = new ParserBuilder<ExplicitTokensTokens, double>();
var result = builder.BuildParser(parserInstance, ParserType.EBNF_LL_RECURSIVE_DESCENT, "expression");


return result;
}

Expand All @@ -109,6 +111,9 @@ public void BuildParserTest()
Check.That(parser.IsOk).IsTrue();
Check.That(parser.Result).IsNotNull();
var r = parser.Result.Parse("2.0 - 2.0 + bozzo + Test");



Check.That(r).IsOkParsing();
// grammar is left associative so expression really is
// (2.0 - (2.0 + (bozzo + Test))) = 2 - ( 2 + (42 + 0)) = 2 - (2 + 42) = 2 - 44 = -42
Expand All @@ -129,9 +134,12 @@ public void BuildExpressionParserTest()
var json = $@"{{
{tree.ToJson()}
}}";

var root = graphviz.VisitTree(tree);
string graph = graphviz.Graph.Compile();

Check.That(graph).Contains(@"label=""\""bozzo\""""")
.And.Contains(@"label=""\""+\""""");

Check.That(r.Result).IsEqualTo(2 - 2 + 42 + 0);
}

Expand Down
111 changes: 111 additions & 0 deletions sly/parser/generator/visitor/ConcreteSyntaxTreeWalker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System.Collections.Generic;
using System.Linq;
using sly.lexer;
using sly.parser.syntax.tree;

namespace sly.parser.generator.visitor
{
public class ConcreteSyntaxTreeWalker<IN, OUT> where IN : struct
{

public IConcreteSyntaxTreeVisitor<IN,OUT> Visitor { get; set; }

public ConcreteSyntaxTreeWalker(IConcreteSyntaxTreeVisitor<IN, OUT> visitor)
{
Visitor = visitor;
}

private OUT VisitLeaf(SyntaxLeaf<IN> leaf)
{
if (leaf.Token.IsIndent)
{
return Visitor.VisitLeaf(leaf.Token);
}
else if (leaf.Token.IsUnIndent)
{
return Visitor.VisitLeaf(leaf.Token);
}
else if (leaf.Token.IsExplicit)
{
return Visitor.VisitLeaf(leaf.Token);
}
return Visitor.VisitLeaf(leaf.Token);
}

public OUT Visit(ISyntaxNode<IN> n)
{
switch (n)
{
case SyntaxLeaf<IN> leaf:
return VisitLeaf(leaf);
case GroupSyntaxNode<IN> node:
return Visit(node);
case ManySyntaxNode<IN> node:
return Visit(node);
case OptionSyntaxNode<IN> node:
return Visit(node);
case SyntaxNode<IN> node:
return Visit(node);
case SyntaxEpsilon<IN> epsilon:
{
return Visitor.VisitEpsilon();
}
default:
return Visitor.VisitLeaf(new Token<IN>() {TokenID = default(IN),SpanValue="NULL".ToCharArray()});
}
}

private OUT Visit(GroupSyntaxNode<IN> node)
{
return Visit(node as SyntaxNode<IN>);
}

private OUT Visit(OptionSyntaxNode<IN> node)
{
var child = node.Children != null && node.Children.Any<ISyntaxNode<IN>>() ? node.Children[0] : null;
if (child == null || node.IsEmpty)
{
Visitor.VisitOptionNode(false, default(OUT));
}
var r = Visit(child);
return r;
}


private OUT Visit(SyntaxNode<IN> node)
{

var children = new List<OUT>();

foreach (var n in node.Children)
{
var v = Visit(n);

children.Add(v);
}


//return callback(node, children);
return Visitor.VisitNode(node,children);
}

private OUT Visit(ManySyntaxNode<IN> manyNode)
{

var children = new List<OUT>();

foreach (var n in manyNode.Children)
{
var v = Visit(n);

children.Add(v);
}


//return callback(node, children);
return Visitor.VisitManyNode(manyNode,children);
}


}
}
Loading

0 comments on commit 77236f2

Please sign in to comment.