Replies: 8 comments
-
Could you provide a reproducible minimal example? Do you want to do something like #112? |
Beta Was this translation helpful? Give feedback.
-
The grammar is a bit too complicated to give you an example but here is my question as clear as I can make it: suppose that you want a binary parser to parse degits (0 or 1) what I want to achieve is the following
please note that this is the simplest example I could think of. Even chatgpt (even less google) could not help. the main idea is: parser1 parses a value and pass it to the next parser. just like parser2(arg: parser1Result) I hope this is clear enough. |
Beta Was this translation helpful? Give feedback.
-
Your simple example with 0s and 1s you could trivially implement as such: final zero = '0'.toParser();
final one = '1'.toParser();
final parser = [seq2(zero, one), one].toChoiceParser().star().flatten(); For the a more generic case, where you build the next parser dynamically while parsing, you can use final zero = '0'.toParser();
final one = '1'.toParser();
final parser = [zero, one]
.toChoiceParser()
.callCC<String>((continuation, context) {
// Parse the original choice parser (zero or one).
final result = continuation(context);
// If this is a success and the result is '0', build a new parser
// and continue with that:
if (result case Success(value: '0')) {
return '1'.toParser().parseOn(result);
}
// Otherwise just return the result of the original choice parser.
return result;
})
.star()
.flatten(); Keep in mind that this approach can quickly yield slow and hard to understand parsers (you are modifying the grammar on the fly). |
Beta Was this translation helpful? Give feedback.
-
Thank you very much for your response. I am using you amazing project to parse graphql schemas and generate Dart/Java code. Right now: I implemented the parser and save everything in memory in one step and then do the semantic checks once this is done. I want to have two steps: 1st step: Parse and save important data in memory. This is way in some parser I needed to arguments such the (The graphql Type on which a given projected has been made) |
Beta Was this translation helpful? Give feedback.
-
Hello again. I have the following parser that parses This means that the parser will parse things like 'odd:3', 'even:4', 'odd:10', 'even:11' but I have one condition (for my graphql semantic validations) the integer parser should take a boolean value to tell it what to expect (even = true and odd = false) now here is my simple implemenation:
as you can see in the comment, I can get the If someone can give me a hint or just say it is not possible I would really appreciate! |
Beta Was this translation helpful? Give feedback.
-
This is how pretty much any compiler / code transformator works. For separation of concerns / easy testability / easy extensibility you want to keep parsing separate from everything else (semantic analysis, code generation, ...).
It looks to me like you are mixing in semantic analysis and the parsing. It would be much simpler, if you would check the even-odd thing after parsing on the resulting parse tree: final parser = seq3(
['even'.toParser(), 'odd'.toParser()].toChoiceParser(),
char(':'),
digit().plus().flatten(),
).map3((key, _, value) => MapEntry(key, int.parse(value)));
// 1. Parse
final result = parser.parse('even:1').value;
// 2. Validation
if (entry.key == 'even' && !entry.value.isEven)) throw ValidationError('Even entry is odd');
if (entry.key == 'odd' && !entry.value.isOdd)) throw ValidationError('Odd entry is even'); If you really wanted, you can fold this even-odd check into the grammar itself. But again, none of the example you provided so far require that: final parser =
seq3(
['even'.toParser(), 'odd'.toParser()].toChoiceParser(),
char(':'),
digit().plus().flatten(),
)
.map3((key, _, value) => MapEntry(key, int.parse(value)))
.where(
(entry) =>
(entry.key == 'even' && entry.value.isEven) ||
(entry.key == 'odd' && entry.value.isOdd),
message: 'Value does not match key',
);
This example fits perfectly into the example I gave with #191 (comment). Just replace |
Beta Was this translation helpful? Give feedback.
-
Yes I guess there is no way to do what I wanted to achieve. What I wanted to do is to throw an exception on the right spot! meaning I do parse a given file and save data to memory then parse again (second time with data in memory) to check the semantics. AKA multipasse compiling. So all the example I was giving is an over simplification of the grammar I am working on. grammar I figured out another way: Thank you for your support |
Beta Was this translation helpful? Give feedback.
-
That's the way to go. There is the |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Here is a pseudo example of what I want to achieve:
Beta Was this translation helpful? Give feedback.
All reactions