Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabling scoping mechanism #35

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
5 changes: 3 additions & 2 deletions src/Parlot/Compilation/CompilationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ namespace Parlot.Compilation
/// <summary>
/// Reprensents the context of a compilation phase, coordinating all the parsers involved.
/// </summary>
public class CompilationContext
public class CompilationContext<TParseContext>
where TParseContext : ParseContext
{
private int _number = 0;

Expand All @@ -18,7 +19,7 @@ public CompilationContext()
/// <summary>
/// Gets the expression containing the the <see cref="ParseContext"/> instance for the parser.
/// </summary>
public ParameterExpression ParseContext { get; } = Expression.Parameter(typeof(ParseContext));
public ParameterExpression ParseContext { get; } = Expression.Parameter(typeof(TParseContext));

/// <summary>
/// Gets or sets a counter used to generate unique variable names.
Expand Down
11 changes: 6 additions & 5 deletions src/Parlot/Compilation/CompiledParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,19 @@ public interface ICompiledParser
/// in order to expose is as as standard parser contract.
/// </summary>
/// <remarks>
/// This class is used in <see cref="Parser{T}.Compile"/>.
/// This class is used in <see cref="Parsers.Compile{T, TParseContext}"/>.
/// </remarks>
public class CompiledParser<T> : Parser<T>, ICompiledParser
public class CompiledParser<T, TParseContext> : Parser<T, TParseContext>, ICompiledParser
where TParseContext : ParseContext
{
private readonly Func<ParseContext, ValueTuple<bool, T>> _parse;
private readonly Func<TParseContext, ValueTuple<bool, T>> _parse;

public CompiledParser(Func<ParseContext, ValueTuple<bool, T>> parse)
public CompiledParser(Func<TParseContext, ValueTuple<bool, T>> parse)
{
_parse = parse ?? throw new ArgumentNullException(nameof(parse));
}

public override bool Parse(ParseContext context, ref ParseResult<T> result)
public override bool Parse(TParseContext context, ref ParseResult<T> result)
{
var start = context.Scanner.Cursor.Offset;
var parsed = _parse(context);
Expand Down
150 changes: 116 additions & 34 deletions src/Parlot/Compilation/ExpressionHelper.cs

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions src/Parlot/Compilation/ICompilable.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
namespace Parlot.Compilation
{
public interface ICompilable
public interface ICompilable<TParseContext>
where TParseContext : Fluent.ParseContext
{
/// <summary>
/// Creates a compiled representation of a parser.
/// </summary>
/// <param name="context">The current compilation context.</param>
CompilationResult Compile(CompilationContext context);
CompilationResult Compile(CompilationContext<TParseContext> context);
}
}
17 changes: 9 additions & 8 deletions src/Parlot/Fluent/Between.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@

namespace Parlot.Fluent
{
public sealed class Between<A, T, B> : Parser<T>, ICompilable
public sealed class Between<A, T, B, TParseContext> : Parser<T, TParseContext>, ICompilable<TParseContext>
where TParseContext : ParseContext
{
private readonly Parser<T> _parser;
private readonly Parser<A> _before;
private readonly Parser<B> _after;
private readonly Parser<T, TParseContext> _parser;
private readonly Parser<A, TParseContext> _before;
private readonly Parser<B, TParseContext> _after;

public Between(Parser<A> before, Parser<T> parser, Parser<B> after)
public Between(Parser<A, TParseContext> before, Parser<T, TParseContext> parser, Parser<B, TParseContext> after)
{
_before = before ?? throw new ArgumentNullException(nameof(before));
_parser = parser ?? throw new ArgumentNullException(nameof(parser));
_after = after ?? throw new ArgumentNullException(nameof(after));
}

public override bool Parse(ParseContext context, ref ParseResult<T> result)
public override bool Parse(TParseContext context, ref ParseResult<T> result)
{
context.EnterParser(this);

Expand All @@ -35,7 +36,7 @@ public override bool Parse(ParseContext context, ref ParseResult<T> result)
{
context.Scanner.Cursor.ResetPosition(start);
return false;
}
}

var parsedB = new ParseResult<B>();

Expand All @@ -48,7 +49,7 @@ public override bool Parse(ParseContext context, ref ParseResult<T> result)
return true;
}

public CompilationResult Compile(CompilationContext context)
public CompilationResult Compile(CompilationContext<TParseContext> context)
{
var result = new CompilationResult();

Expand Down
11 changes: 6 additions & 5 deletions src/Parlot/Fluent/Capture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@

namespace Parlot.Fluent
{
public sealed class Capture<T> : Parser<TextSpan>, ICompilable
public sealed class Capture<T, TParseContext> : Parser<TextSpan, TParseContext>, ICompilable<TParseContext>
where TParseContext : ParseContext
{
private readonly Parser<T> _parser;
private readonly Parser<T, TParseContext> _parser;

public Capture(Parser<T> parser)
public Capture(Parser<T, TParseContext> parser)
{
_parser = parser;
}

public override bool Parse(ParseContext context, ref ParseResult<TextSpan> result)
public override bool Parse(TParseContext context, ref ParseResult<TextSpan> result)
{
context.EnterParser(this);

Expand All @@ -36,7 +37,7 @@ public override bool Parse(ParseContext context, ref ParseResult<TextSpan> resul
return false;
}

public CompilationResult Compile(CompilationContext context)
public CompilationResult Compile(CompilationContext<TParseContext> context)
{
var result = new CompilationResult();

Expand Down
7 changes: 4 additions & 3 deletions src/Parlot/Fluent/CharLiteral.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

namespace Parlot.Fluent
{
public sealed class CharLiteral : Parser<char>, ICompilable
public sealed class CharLiteral<TParseContext> : Parser<char, TParseContext>, ICompilable<TParseContext>
where TParseContext : ParseContext
{
public CharLiteral(char c)
{
Expand All @@ -12,7 +13,7 @@ public CharLiteral(char c)

public char Char { get; }

public override bool Parse(ParseContext context, ref ParseResult<char> result)
public override bool Parse(TParseContext context, ref ParseResult<char> result)
{
context.EnterParser(this);

Expand All @@ -27,7 +28,7 @@ public override bool Parse(ParseContext context, ref ParseResult<char> result)
return false;
}

public CompilationResult Compile(CompilationContext context)
public CompilationResult Compile(CompilationContext<TParseContext> context)
{
var result = new CompilationResult();

Expand Down
11 changes: 6 additions & 5 deletions src/Parlot/Fluent/DecimalLiteral.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

namespace Parlot.Fluent
{
public sealed class DecimalLiteral : Parser<decimal>, ICompilable
public sealed class DecimalLiteral<TParseContext> : Parser<decimal, TParseContext>, ICompilable<TParseContext>
where TParseContext : ParseContext
{
private readonly NumberOptions _numberOptions;

Expand All @@ -14,7 +15,7 @@ public DecimalLiteral(NumberOptions numberOptions = NumberOptions.Default)
_numberOptions = numberOptions;
}

public override bool Parse(ParseContext context, ref ParseResult<decimal> result)
public override bool Parse(TParseContext context, ref ParseResult<decimal> result)
{
context.EnterParser(this);

Expand All @@ -40,8 +41,8 @@ public override bool Parse(ParseContext context, ref ParseResult<decimal> result
#endif

if (decimal.TryParse(sourceToParse, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var value))
{
result.Set(start, end, value);
{
result.Set(start, end, value);
return true;
}
}
Expand All @@ -51,7 +52,7 @@ public override bool Parse(ParseContext context, ref ParseResult<decimal> result
return false;
}

public CompilationResult Compile(CompilationContext context)
public CompilationResult Compile(CompilationContext<TParseContext> context)
{
var result = new CompilationResult();

Expand Down
12 changes: 6 additions & 6 deletions src/Parlot/Fluent/Deferred.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@

namespace Parlot.Fluent
{
public sealed class Deferred<T> : Parser<T>, ICompilable
public sealed class Deferred<T, TParseContext> : Parser<T, TParseContext>, ICompilable<TParseContext>
where TParseContext : ParseContext
{

public Parser<T> Parser { get; set; }
public Parser<T, TParseContext> Parser { get; set; }

public Deferred()
{
}

public Deferred(Func<Deferred<T>, Parser<T>> parser)
public Deferred(Func<Deferred<T, TParseContext>, Parser<T, TParseContext>> parser)
{
Parser = parser(this);
}

public override bool Parse(ParseContext context, ref ParseResult<T> result)
public override bool Parse(TParseContext context, ref ParseResult<T> result)
{
return Parser.Parse(context, ref result);
}
Expand All @@ -32,7 +32,7 @@ private class Closure
public object Func;
}

public CompilationResult Compile(CompilationContext context)
public CompilationResult Compile(CompilationContext<TParseContext> context)
{
if (Parser == null)
{
Expand Down
13 changes: 7 additions & 6 deletions src/Parlot/Fluent/Discard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,25 @@ namespace Parlot.Fluent
/// <summary>
/// Doesn't parse anything and return the default value.
/// </summary>
public sealed class Discard<T, U> : Parser<U>, ICompilable
public sealed class Discard<T, U, TParseContext> : Parser<U, TParseContext>, ICompilable<TParseContext>
where TParseContext : ParseContext
{
private readonly Parser<T> _parser;
private readonly Parser<T, TParseContext> _parser;
private readonly U _value;

public Discard(Parser<T> parser)
public Discard(Parser<T, TParseContext> parser)
{
_value = default(U);
_parser = parser;
}

public Discard(Parser<T> parser, U value)
public Discard(Parser<T, TParseContext> parser, U value)
{
_parser = parser;
_value = value;
}

public override bool Parse(ParseContext context, ref ParseResult<U> result)
public override bool Parse(TParseContext context, ref ParseResult<U> result)
{
context.EnterParser(this);

Expand All @@ -38,7 +39,7 @@ public override bool Parse(ParseContext context, ref ParseResult<U> result)
return false;
}

public CompilationResult Compile(CompilationContext context)
public CompilationResult Compile(CompilationContext<TParseContext> context)
{
var result = new CompilationResult();

Expand Down
7 changes: 4 additions & 3 deletions src/Parlot/Fluent/Empty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ namespace Parlot.Fluent
/// <summary>
/// Doesn't parse anything and return the default value.
/// </summary>
public sealed class Empty<T> : Parser<T>, ICompilable
public sealed class Empty<T, TParseContext> : Parser<T, TParseContext>, ICompilable<TParseContext>
where TParseContext : ParseContext
{
private readonly T _value;

Expand All @@ -20,7 +21,7 @@ public Empty(T value)
_value = value;
}

public override bool Parse(ParseContext context, ref ParseResult<T> result)
public override bool Parse(TParseContext context, ref ParseResult<T> result)
{
context.EnterParser(this);

Expand All @@ -29,7 +30,7 @@ public override bool Parse(ParseContext context, ref ParseResult<T> result)
return true;
}

public CompilationResult Compile(CompilationContext context)
public CompilationResult Compile(CompilationContext<TParseContext> context)
{
var result = new CompilationResult();

Expand Down
13 changes: 7 additions & 6 deletions src/Parlot/Fluent/Eof.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ namespace Parlot.Fluent
/// <summary>
/// Successful when the cursor is at the end of the string.
/// </summary>
public sealed class Eof<T> : Parser<T>, ICompilable
public sealed class Eof<T, TParseContext> : Parser<T, TParseContext>, ICompilable<TParseContext>
where TParseContext : ParseContext
{
private readonly Parser<T> _parser;
private readonly Parser<T, TParseContext> _parser;

public Eof(Parser<T> parser)
public Eof(Parser<T, TParseContext> parser)
{
_parser = parser;
}

public override bool Parse(ParseContext context, ref ParseResult<T> result)
public override bool Parse(TParseContext context, ref ParseResult<T> result)
{
context.EnterParser(this);

Expand All @@ -28,7 +29,7 @@ public override bool Parse(ParseContext context, ref ParseResult<T> result)
return false;
}

public CompilationResult Compile(CompilationContext context)
public CompilationResult Compile(CompilationContext<TParseContext> context)
{
var result = new CompilationResult();

Expand All @@ -55,7 +56,7 @@ public CompilationResult Compile(CompilationContext context)
context.DiscardResult
? Expression.Empty()
: Expression.Assign(value, parserCompileResult.Value),
Expression.Assign(success, Expression.Constant(true, typeof(bool)))
Expression.Assign(success, Expression.Constant(true, typeof(bool)))
)
)
)
Expand Down
Loading