I have a series of string like this:
(((S|69|L || S|69|R || S|72|L || S|72|R) && ((S|62|L && (S|78|L || S|55|L) && (S|77|L || S|1|L)) || (S|62|R && (S|78|R || S|55|R) && (S|77|R || S|1|R)))) && (M|34|L || M|34|R) && (((M|40|L && M|39|L && M|36|L) || (M|40|R && M|39|R && M|36|R)) || ((M|38|L && M|36|L && M|37|L) || (M|38|R && M|36|R && M|37|R))))
And I need to run items that look like S|69|L
to see if they satisfy this criteria. You can see that it's a series of && or || operations organized by parentheses.
I'm trying to use this tutorial: https://github.com/petitparser/dart-petitparser
But I'm having trouble getting off of the ground. Can anyone give me an example to get started with this? Maybe I just need more coffee...
Update: Making progress. This at least pulls off outside parentheses. I think I just need to continue to play with it, but I would still appreciate any tips for those who know how this works.
String testString = '((1||2) || 3)';
final inner = undefined();
final paren = (char('(').trim() & inner.star().flatten() & char(')').trim())
.map((values) => values[1]);
inner.set(paren | pattern('^)'));
final parser = inner.end();
final result = parser.parse(testString);
print(result.value);
The grammar you provide in the question seems to work for me and the provided example inputs pass.
A couple of tips:
If you are not interested in the parser output, instead of calling parser.parse(input)
you could use parser.accept(input)
to get a boolean.
Similarly, if you are not interested in the output, you can drop the calls to flatten()
and map(...)
. Both are used to build an AST. Furthermore, flatten()
hides the generated tree, which can make it hard to see what is happening.
For the actual values you could use a primitive parser like the following. However, not sure what your exact specification is?
final primitive = (uppercase() & char('|') & digit().plus() & char('|') & uppercase()).flatten().trim();
outer
) like so:final outer = undefined();
final inner = undefined();
final operator = string('&&') | string('||');
outer.set(inner.separatedBy(operator));
final paren = char('(').trim() & outer & char(')').trim();
inner.set(paren | primitive);
final parser = outer.end();
final builder = ExpressionBuilder();
builder.group().primitive(primitive);
builder.group()
.wrapper(char('(').trim(), char(')').trim(), (l, v, r) => [l, v, r]);
builder.group()
..left(string('&&').trim(), (a, op, b) => [a, '&&', b])
..left(string('||').trim(), (a, op, b) => [a, '||', b]);
final parser = builder.build().end();