// fraction = literal-literal/literal | literal literal/literal | literal/literal private ParserRule[] GetFractionRules() => new ParserRule[] { // Mixed number fraction rule e.g. 1 1/2 ParserRuleBuilder .New() .Token <LiteralAmountToken>(Literal) .Condition(buffer => buffer.TryConsume(' ') || buffer.TryConsume('-')) .Token <LiteralAmountToken>(Literal) .Condition(buffer => buffer.TryConsume('/')) .Token <LiteralAmountToken>(Literal) .Map(tokens => { var wholeNumber = tokens[0] as LiteralAmountToken; var numerator = tokens[1] as LiteralAmountToken; var denominator = tokens[2] as LiteralAmountToken; return(ParserRuleResult.Success(AmountToken.Fraction(wholeNumber, numerator, denominator))); }) .Build(), // Standard fraction rule e.g. 1/2 ParserRuleBuilder .New() .Token <LiteralAmountToken>(Literal) .Condition(buffer => buffer.TryConsume('/')) .Token <LiteralAmountToken>(Literal) .Map(tokens => { var numerator = tokens[0] as LiteralAmountToken; var denominator = tokens[1] as LiteralAmountToken; return(ParserRuleResult.Success(AmountToken.Fraction(wholeNumber: null, numerator, denominator))); }) .Build() };
// amount = range | fraction | literal private ParserRule[] GetAmountRules() => new ParserRule[] { // Range e.g. 1-4 ParserRuleBuilder .New() .Token <RangeAmountToken>(Range) // Ensure all input is consumed .Condition(buffer => !buffer.HasNext()) .Map(tokens => { var range = tokens[0] as RangeAmountToken; return(ParserRuleResult.Success(range)); }) .Build(), // Fraction e.g. 1/2 ParserRuleBuilder .New() .Token <FractionalAmountToken>(Fraction) // Ensure all input is consumed .Condition(buffer => !buffer.HasNext()) .Map(tokens => { var fraction = tokens[0] as FractionalAmountToken; return(ParserRuleResult.Success(fraction)); }) .Build(), // Literal e.g. 2 ParserRuleBuilder .New() .Token <LiteralAmountToken>(Literal) // Ensure all input is consumed .Condition(buffer => !buffer.HasNext()) .Map(tokens => { var literal = tokens[0] as LiteralAmountToken; return(ParserRuleResult.Success(literal)); }) .Build() };
// range = fraction-fraction | literal-literal private ParserRule[] GetRangeRules() => new ParserRule[] { // Fractional range e.g. 1/4-1/3 ParserRuleBuilder .New() .Token <FractionalAmountToken>(Fraction) .Condition(buffer => buffer.OptionallyConsume(' ')) .Condition(buffer => buffer.TryConsume('-')) .Condition(buffer => buffer.OptionallyConsume(' ')) .Token <FractionalAmountToken>(Fraction) .Map(tokens => { var lowerBound = tokens[0] as FractionalAmountToken; var upperBound = tokens[1] as FractionalAmountToken; return(ParserRuleResult.Success(AmountToken.Range(lowerBound, upperBound))); }) .Build(), // Literal range e.g. 1-2 ParserRuleBuilder .New() .Token <LiteralAmountToken>(Literal) .Condition(buffer => buffer.OptionallyConsume(' ')) .Condition(buffer => buffer.TryConsume('-')) .Condition(buffer => buffer.OptionallyConsume(' ')) .Token <LiteralAmountToken>(Literal) .Map(tokens => { var lowerBound = tokens[0] as LiteralAmountToken; var upperBound = tokens[1] as LiteralAmountToken; return(ParserRuleResult.Success(AmountToken.Range(lowerBound, upperBound))); }) .Build() };