Skip to content

Commit

Permalink
ExpressionSample - reimplement stmt parser in terms of expr
Browse files Browse the repository at this point in the history
  • Loading branch information
bobbymcr committed Apr 15, 2018
1 parent e279c89 commit 07b7062
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 110 deletions.
2 changes: 1 addition & 1 deletion projects/ExpressionSample/GWParse.Test/Statements/Dim.cs
Expand Up @@ -11,7 +11,7 @@ public sealed class Dim
[InlineData("DIM R(1)", "Dim(NumA(R, NumL(1)))")]
[InlineData("DIM R(1,2)", "Dim(NumA(R, NumL(1), NumL(2)))")]
[Theory]
public void Valid(string input, string output)
public void OneItem(string input, string output)
{
Test.Good(input, output);
}
Expand Down
10 changes: 9 additions & 1 deletion projects/ExpressionSample/GWParse/Expressions/Expr.cs
Expand Up @@ -11,7 +11,11 @@ namespace GWParse.Expressions

internal static class Expr
{
private static readonly Parser<BasicExpression> Any = Parse.Ref(() => Root);
public static readonly Parser<BasicExpression> Any = Parse.Ref(() => Root);

public static readonly Parser<BasicExpression> AnyArray = Var.ArrayAny;

public static readonly Parser<BasicExpression> AnyVar = Var.Any;

private static readonly Parser<BasicExpression> Paren =
from lp in Ch.LeftParen
Expand Down Expand Up @@ -144,6 +148,10 @@ private static class Var
public static readonly Parser<BasicExpression> NumAny = NumArray.Or(NumScalar);

public static readonly Parser<BasicExpression> StrAny = StrArray.Or(StrScalar);

public static readonly Parser<BasicExpression> ArrayAny = StrArray.Or(NumArray);

public static readonly Parser<BasicExpression> Any = StrAny.Or(NumAny);
}

private static class Str
Expand Down
Expand Up @@ -4,51 +4,19 @@

namespace GWParse.Statements
{
using System;
using GWParse.Expressions;

internal sealed class AssignmentStatement : BasicStatement
{
private static readonly IExpressionVisitor Visitor = new LValueVisitor();

private readonly BasicExpression left;
private readonly BasicExpression right;

public AssignmentStatement(BasicExpression left, BasicExpression right)
{
this.left = EnsureLValue(left);
this.left = left;
this.right = right;
}

public override string ToString() => "Assign(" + this.left + ", " + this.right + ")";

private static BasicExpression EnsureLValue(BasicExpression left)
{
left.Accept(Visitor);
return left;
}

private sealed class LValueVisitor : IExpressionVisitor
{
public void Array(BasicType type, string name, BasicExpression[] subs)
{
// Allowed
}

public void Literal(BasicType type, object o)
{
throw new NotSupportedException("Not an L-value.");
}

public void Operator(string name, BasicExpression[] operands)
{
throw new NotSupportedException("Not an L-value.");
}

public void Variable(BasicType type, string name)
{
// Allowed
}
}
}
}
Expand Up @@ -4,49 +4,17 @@

namespace GWParse.Statements
{
using System;
using GWParse.Expressions;

internal sealed class DimensionStatement : BasicStatement
{
private static readonly IExpressionVisitor Visitor = new ArrayVisitor();

private readonly BasicExpression a;

public DimensionStatement(BasicExpression a)
{
this.a = EnsureArray(a);
this.a = a;
}

public override string ToString() => "Dim(" + this.a + ")";

private static BasicExpression EnsureArray(BasicExpression a)
{
a.Accept(Visitor);
return a;
}

private sealed class ArrayVisitor : IExpressionVisitor
{
public void Array(BasicType type, string name, BasicExpression[] subs)
{
// Allowed
}

public void Literal(BasicType type, object o)
{
throw new NotSupportedException("Not an array.");
}

public void Operator(string name, BasicExpression[] operands)
{
throw new NotSupportedException("Not an array.");
}

public void Variable(BasicType type, string name)
{
throw new NotSupportedException("Not an array.");
}
}
}
}
50 changes: 8 additions & 42 deletions projects/ExpressionSample/GWParse/Statements/Stmt.cs
Expand Up @@ -5,6 +5,8 @@
namespace GWParse.Statements
{
using System;
using System.Collections.Generic;
using System.Linq;
using GWParse.Expressions;
using Sprache;

Expand All @@ -27,14 +29,14 @@ internal static class Stmt

private static readonly Parser<BasicStatement> Dim =
from k in Parse.IgnoreCase("DIM").Token()
from s in Parse.AnyChar.AtLeastOnce().Text()
select DimA(s);
from a in Expr.AnyArray
select new DimensionStatement(a);

private static readonly Parser<BasicStatement> Assign =
from left in Parse.CharExcept('=').AtLeastOnce().Text()
from o in Parse.Char('=')
from right in Parse.AnyChar.AtLeastOnce().Text()
select Asgn(left, right);
from left in Expr.AnyVar
from o in Parse.Char('=').Token()
from right in Expr.Any
select new AssignmentStatement(left, right);

private static readonly Parser<BasicStatement> Any =
Rem.Or(Cls).Or(Dim).Or(Assign);
Expand All @@ -50,41 +52,5 @@ public static BasicStatement FromString(string input)
throw new FormatException("Bad statement '" + input + "'.", e);
}
}

private static BasicStatement Asgn(string left, string right)
{
try
{
return new AssignmentStatement(Expr(left), Expr(right));
}
catch (NotSupportedException e)
{
throw new ParseException(e.Message);
}
}

private static BasicStatement DimA(string a)
{
try
{
return new DimensionStatement(Expr(a));
}
catch (NotSupportedException e)
{
throw new ParseException(e.Message);
}
}

private static BasicExpression Expr(string s)
{
try
{
return BasicExpression.FromString(s);
}
catch (FormatException e)
{
throw new ParseException(e.Message);
}
}
}
}

0 comments on commit 07b7062

Please sign in to comment.