Skip to content

Commit

Permalink
Fix compilation issues (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastienros authored Jan 5, 2022
1 parent 2ab5692 commit 09257a2
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 30 deletions.
19 changes: 18 additions & 1 deletion docs/parsers.md
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ Point { x: 1, y: 2}

### ElseError

Fails parsing with a custom error message.
Fails parsing with a custom error message when the inner parser didn't match.

```c#
Parser<T> ElseError(string message)
Expand All @@ -645,12 +645,29 @@ failure: "Expected an integer at (1:3)

### Error

Fails parsing with a custom error message when the inner parser matched.

```c#
Parser<T> Error(string message)
Parser<U> Error<U>(string message)
```

Usage:

```c#
var parser =
Terms.Char('a')
.Or(Terms.Char('b')
.Or(Terms.Char('c').Error("Unexpected char c")

parser.Parse("1,");
```

Result:

```
failure: "Expected an integer at (1:3)
```
### When

Adds some additional logic for a parser to succeed.
Expand Down
51 changes: 26 additions & 25 deletions src/Parlot/Fluent/Error.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,36 @@ public CompilationResult Compile(CompilationContext context)
var value = context.DeclareValueVariable(result, Expression.Default(typeof(T)));

// parse1 instructions
// success = true
//
// if (!parser1.Success)
// if (parser1.Success)
// {
// value = parser1.Value
// }
// else
// {
// throw new ParseException(_message, context.Scanner.Cursor.Position);
// }
//
// value = parser1.Value
//

var parserCompileResult = _parser.Build(context, requireResult: true);

var block = Expression.Block(
parserCompileResult.Variables,
parserCompileResult.Body
.Append(Expression.Assign(value, parserCompileResult.Value))
.Append(
Expression.IfThen(
Expression.Not(parserCompileResult.Success),
Expression.IfThenElse(
parserCompileResult.Success,
context.DiscardResult
? Expression.Empty()
: Expression.Assign(value, parserCompileResult.Value),
context.ThrowParseException(Expression.Constant(_message))
)
).Append(
context.DiscardResult
? Expression.Empty()
: Expression.Assign(value, parserCompileResult.Value)
)


))
);

result.Body.Add(block);

return result;
Expand Down Expand Up @@ -96,31 +100,27 @@ public CompilationResult Compile(CompilationContext context)
{
var result = new CompilationResult();

_ = context.DeclareSuccessVariable(result, true);
var value = context.DeclareValueVariable(result, Expression.Default(typeof(T)));
_ = context.DeclareSuccessVariable(result, false);
_ = context.DeclareValueVariable(result, Expression.Default(typeof(T)));

// parse1 instructions
//
// success = false;
//
// if (parser1.Success)
// {
// value = parser1.Value;
// throw new ParseException(_message, context.Scanner.Cursor.Position);
// }

var parserCompileResult = _parser.Build(context, requireResult: true);
var parserCompileResult = _parser.Build(context, requireResult: false);

var block = Expression.Block(
parserCompileResult.Variables,
parserCompileResult.Body
.Append(
Expression.IfThen(
parserCompileResult.Success,
Expression.Block(
context.DiscardResult
? Expression.Empty()
: Expression.Assign(value, parserCompileResult.Value),
context.ThrowParseException(Expression.Constant(_message))
)
context.ThrowParseException(Expression.Constant(_message))
)
)
);
Expand Down Expand Up @@ -153,24 +153,25 @@ public override bool Parse(ParseContext context, ref ParseResult<U> result)
throw new ParseException(_message, context.Scanner.Cursor.Position);
}

return true;
return false;
}

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

_ = context.DeclareSuccessVariable(result, true);
_ = context.DeclareSuccessVariable(result, false);
_ = context.DeclareValueVariable(result, Expression.Default(typeof(U)));

// parse1 instructions
// success = false;
//
// if (parser1.Success)
// {
// throw new ParseException(_message, context.Scanner.Cursor.Position);
// }

var parserCompileResult = _parser.Build(context, requireResult: true);
var parserCompileResult = _parser.Build(context, requireResult: false);

var block = Expression.Block(
parserCompileResult.Variables,
Expand Down
2 changes: 1 addition & 1 deletion src/Parlot/Fluent/OneOf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public CompilationResult Compile(CompilationContext context)
var start = context.DeclarePositionVariable(result);

block = Expression.Block(
context.SkipWhiteSpace(),
context.ParserSkipWhiteSpace(),
switchExpr,
Expression.IfThen(
Expression.IsFalse(success),
Expand Down
15 changes: 14 additions & 1 deletion test/Parlot.Tests/CompileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -439,12 +439,25 @@ public void CompiledWhenShouldResetPositionWhenFalse()
Assert.True(evenIntegers.TryParse("1235", out var result1));
Assert.Equal(1235, result1.Item2);
}

[Fact]
public void ErrorShouldThrowIfParserSucceeds()
{
Assert.False(Literals.Char('a').Error("'a' was not expected").Compile().TryParse("a", out _, out var error));
Assert.Equal("'a' was not expected", error.Message);

Assert.False(Literals.Char('a').Error<int>("'a' was not expected").Compile().TryParse("a", out _, out error));
Assert.Equal("'a' was not expected", error.Message);
}

[Fact]
public void ErrorShouldReturnFalseThrowIfParserFails()
{
Assert.False(Literals.Char('a').Error("'a' was not expected").Compile().TryParse("b", out _, out var error));
Assert.Null(error);

Assert.False(Literals.Char('a').Error<int>("'a' was not expected").Compile().TryParse("b", out _, out error));
Assert.Null(error);
}

[Fact]
Expand Down
24 changes: 22 additions & 2 deletions test/Parlot.Tests/FluentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -514,15 +514,35 @@ public void ErrorShouldThrowIfParserSucceeds()
{
Assert.False(Literals.Char('a').Error("'a' was not expected").TryParse("a", out _, out var error));
Assert.Equal("'a' was not expected", error.Message);

Assert.False(Literals.Char('a').Error<int>("'a' was not expected").TryParse("a", out _, out error));
Assert.Equal("'a' was not expected", error.Message);
}


[Fact]
public void ErrorShouldReturnFalseThrowIfParserFails()
{
Assert.False(Literals.Char('a').Error("'a' was not expected").TryParse("b", out _, out var error));
Assert.Null(error);

Assert.False(Literals.Char('a').Error<int>("'a' was not expected").TryParse("b", out _, out error));
Assert.Null(error);
}

[Fact]
public void ErrorShouldThrow()
{
Assert.False(Literals.Char('a').Error("'a' was not expected").TryParse("a", out _, out var error));
Assert.Equal("'a' was not expected", error.Message);
}


[Fact]
public void ErrorShouldResetPosition()
{
Assert.False(Literals.Char('a').Error("'a' was not expected").TryParse("a", out _, out var error));
Assert.Equal("'a' was not expected", error.Message);
}

[Fact]
public void ElseErrorShouldThrowIfParserFails()
{
Expand Down

0 comments on commit 09257a2

Please sign in to comment.