/// <summary> /// A very simple calculator parser /// </summary> public Calculator() { // creating rules and assigning names (for debugging) group = new Rule("Group"); term = new Rule("Term"); factor = new Rule("Factor"); expression = new Rule("Expression"); integer = new Rule("Integer", Prims.Digit) [OnInteger]; // creating sub parsers Parser add = Ops.Sequence('+', term); // attaching semantic action add.Act += OnAdd; // creating sub parsers and attaching semantic action in one swoop Parser sub = Ops.Sequence('-', term)[OnSub]; Parser mult = Ops.Sequence('*', factor)[OnMult]; Parser div = Ops.Sequence('/', factor)[OnDiv]; // assigning parsers to rules group.Parser = Ops.Sequence('(', expression, ')'); factor.Parser = group | integer; term.Parser = Ops.Sequence(factor, Ops.ZeroOrMore(mult | div)); expression.Parser = Ops.Sequence(term, Ops.ZeroOrMore(add | sub)) [OnExpression]; // debuggger debug = new Debugger(Console.Out); debug += factor; debug += term; debug += group; debug += expression; debug += integer; }
public void NoMatchMatch() { Rule d = new Rule("digit", Prims.Digit); AlternativeParser rp = d | d | d; IScanner scan = Provider.NewScanner; ParserMatch m = rp.Parse(scan); Assert.IsFalse(m.Success); Assert.AreEqual(0,scan.Offset); }
public void ThirdMatch() { Rule d = new Rule("digit", Prims.Digit); Rule l = new Rule("letter", Prims.Letter); AlternativeParser rp = d | d | l; IScanner scan = Provider.NewScanner; ParserMatch m = rp.Parse(scan); Assert.IsTrue(m.Success); Assert.AreEqual(1, m.Length); Assert.AreEqual(1, scan.Offset); }
public void FirstMatch() { Rule d = new Rule(); Rule l = new Rule(); d.Parser = Prims.Digit; l.Parser = Prims.Letter; AlternativeParser rp = l | d; IScanner scan = Provider.NewScanner; ParserMatch m = rp.Parse(scan); Assert.IsTrue(m.Success); Assert.AreEqual(1, m.Length); Assert.AreEqual(1, scan.Offset); }
public SimpleCollationRuleParser(bool useDebugger) { // creating sub parsers Parser character = new CharParser(IsCharacter); Parser hexDigit = Prims.HexDigit; Parser newLine = Prims.Eol; Parser whiteSpace = Ops.ZeroOrMore(Prims.WhiteSpace - Prims.Eol); Parser unicodeEscapeCharacter = Ops.Sequence('\\', Ops.Expect("scr0001", "Invalid unicode character escape sequence: missing 'u' after '\\'", 'u'), Ops.Expect("scr0002", "Invalid unicode character escape sequence: missing hexadecimal digit after '\\u'", hexDigit), Ops.Expect("scr0002", "Invalid unicode character escape sequence: missing hexadecimal digit after '\\u'", hexDigit), Ops.Expect("scr0002", "Invalid unicode character escape sequence: missing hexadecimal digit after '\\u'", hexDigit), Ops.Expect("scr0002", "Invalid unicode character escape sequence: missing hexadecimal digit after '\\u'", hexDigit)); // creating rules and assigning names (for debugging) _collationElement = new Rule("collationElement"); _collationGroup = new Rule("collationGroup"); _collationLine = new Rule("collationLine"); _collationRules = new Rule("collationRules"); // assigning parsers to rules // collationElement ::= (unicodeEscapeCharacter | character)+ _collationElement.Parser = Ops.Expect(CollationElementIsUnique, "scr0100", "Duplicate collation element", Ops.OneOrMore(unicodeEscapeCharacter | character)); // collationGroup ::= '(' WS* collationElement WS+ (collationElement WS?)+ ')' _collationGroup.Parser = Ops.Sequence('(', whiteSpace, Ops.Expect("scr0003", "Expected: 2 or more collation elements in collation group (nested collation groups are not allowed)", Ops.Sequence(_collationElement, whiteSpace, _collationElement, whiteSpace)), Ops.Expect("scr0004", "Expected: collation element or close group ')'", Ops.ZeroOrMore( Ops.Sequence(_collationElement, whiteSpace))), Ops.Expect("scr0005", "Expected: group close ')'", ')')); // collationLine ::= (collationElement WS? | collationGroup WS?)+ _collationLine.Parser = Ops.OneOrMore(Ops.Sequence(_collationGroup | _collationElement, whiteSpace)); // collationRules ::= WS? collationLine? (NewLine WS? collationLine?)* EOF _collationRules.Parser = Ops.Expect("scr0006", "Invalid character", Ops.Sequence(whiteSpace, Ops.Optional(_collationLine), Ops.ZeroOrMore(Ops.Sequence(newLine, whiteSpace, Ops.Optional(_collationLine))), Prims.End)); character.Act += new ActionHandler(OnCharacter); unicodeEscapeCharacter.Act += OnUnicodeEscapeCharacter; _collationElement.Act += new ActionHandler(OnCollationElement); _collationGroup.Act += new ActionHandler(OnCollationGroup); _collationGroup.PreParse += new PreParseEventHandler(OnEnterCollationGroup); _collationGroup.PostParse += new PostParseEventHandler(OnExitCollationGroup); _collationLine.Act += new ActionHandler(OnCollationLine); _collationRules.Act += new ActionHandler(OnCollationRules); if (useDebugger) { // debuggger debug = new Debugger(Console.Out); debug += _collationRules; debug += _collationLine; debug += _collationGroup; debug += _collationElement; } }