-
-
Notifications
You must be signed in to change notification settings - Fork 45
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
base: main
Are you sure you want to change the base?
Conversation
Not opposed to it. Right now the solution is to pass a custom instance inheriting from |
Maybe I missed something, but I see 1 major problem with this: how do you handle nested scopes ? the approach I suggested is most likely not the best, but it at least helps solving this problem which sounds like a common use case for parsers. |
splitted ParseContext and ParseContext.Untyped
Generic TParseContext will also probably open possibility to use struct type by restricting to new IParseContext interface and consumers like Fluid can use their own type. |
The other "small" change I made is to make an IParser interface for better variance/covariance (I never remember which one is which) support which, does not work well with classes. |
@npenin That's great! I had to remove the interfaces at some point because it was preventing me from doing some Fluent things in places. I had an
Had a quick look and I couldn't find that. Ideally Can you split this PR in two, one with the Scoped parser and one with the interfaces? I want to deal with the changes independently. |
Unfortunately, I don't think so. If I split it, it will have to still contain all my changes for the typed parsercontext, otherwise, that would be a completely different implementation. Regarding the variance/covariance, there is a flaw in .NET that would prevent from casting a |
Now that I have merged compilation I will be able to focus on your PRs. |
it took me quite some time to get it compile again after your compilation changes. I hope I will not have to do it again ;) |
/// </summary> | ||
/// <typeparam name="T">The input parser type.</typeparam> | ||
/// <typeparam name="TParseContext">The parse context type.</typeparam> | ||
public sealed class Then<T, TParseContext> : Parser<T, TParseContext>, ICompilable<TParseContext> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a new one right?
I assume to just be able to pass an action that can change the context only?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed
Ran the benchmarks, slower by 10%. |
do you know where exactly or is it just a general slowness ? |
Global regression due to interface dispatch, @lahma ? |
Though if there is no possibility of using a "common" |
That would be my guess. Interface dispatch is a lot more costly than regular virtual member call. |
Indeed, I removed the interface and earned back the 10%. |
The new SkipWhiteSpace parser needs to be updated |
@@ -5,22 +5,31 @@ | |||
|
|||
namespace Parlot.Fluent | |||
{ | |||
public abstract partial class Parser<T> | |||
public partial class Parsers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like there is public static class ParserExtensions
for TryParse
it should be a ParserExtensions
for Compile
. Maybe both as partial classes.
|
||
namespace Parlot.Fluent | ||
{ | ||
public partial class ParseContext |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why it should be part of the library. This PR allows to change the type of ParseContext
, so any project could then create their own, and have one that takes a dictionary if they need, or custom properties.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed, I just thought having an example and the possiblity to use such a parser straight ahead would be the right thing to do. but I agree with you
@@ -32,7 +32,7 @@ public ParseContext(Scanner scanner, bool useNewLines = false) | |||
/// <summary> | |||
/// The parser that is used to parse whitespaces and comments. | |||
/// </summary> | |||
public Parser<TextSpan> WhiteSpaceParser { get; set;} | |||
public Parser<TextSpan, ParseContext> WhiteSpaceParser { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it could now be in a custom ParseContext
that deals with char
, since it doesn't make sense for byte based parsers. Then the Literals
or Terms
based parsers could use this new context type, to drive the other parsers generic type. There would then be a new set of binary parsers with another corresponding type.
Or maybe it's a Scanner
concern too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you mixed this comment with my other PR. BTW, it is done as such in my other PR (see StringParseContext).
@sebastienros up ? |
Hi seb,
One more pull request that allows scoped parsers (that required an adaptation to the parsercontext). That allows registering variable declarations in a block statement before actually waiting for the parser to complete