I have 2 Superpower TextParser - each targets to parse a certain input - differentiated by prefix and parameters. I am trying to create a combined parser that gives out the result when either of the TextParser can parse the input. The output is a list with certain strings describing the input.
e.g. Some input and output pair as follows
"interrupt(20)" -> List { "interrupt", "20" }
"insert(20,12)" -> List {"insert", "20", "12" }
"delete(18)" -> Error
For the sample input and output pairs, I wrote the following in C# with superpower reference added.
// Works fine for "insert(12,24)"
string failingTest = "interrupt(12)";
TextParser<List<string>> identifier001 =
from prefix in Span.EqualTo("insert")
from open in Character.EqualTo('(')
from num0 in Character.Numeric.Many()
from comma1 in Character.EqualTo(',')
from num1 in Character.Numeric.Many()
from close in Character.EqualTo(')')
select new List<string> { prefix.ToStringValue(), string.Join("", num0), string.Join("", num1) };
TextParser<List<string>> identifier002 =
from prefix in Span.EqualTo("interrupt")
from open in Character.EqualTo('(')
from num0 in Character.Numeric.Many()
from close in Character.EqualTo(')')
select new List<string> { prefix.ToStringValue(), string.Join("", num0) };
TextParser<List<string>> combined =
from span in identifier001.Or(identifier002)
select span;
var res = combined.Parse(failingTest);
foreach (var item in res)
{
Console.WriteLine(item);
}
My combined identifier cannot parse the input interrupt(12) and gives the following error
Syntax error (line 1, column 3): unexpected
t, expecteds.
Is there any proper way of doing the "Or" combination of the identifiers?
You have to call
Try()after your first parser, then chain it with theOr()function, like this:What happens is that your first parser
identifier001has already consumed the"in"portion of the string, which leavesidentifier002to try and parse the string"terrupt(20)"which fails. The call toTry()tells the parser to backtrack to the point of origin of the previous parser, which is what you want.The documentation on
Try()is this: