public void ParseTest() { LexicalRule digit = LexicalRule.Range('0', '9'); LexerBuilder lexb = new LexerBuilder(); var blank = lexb.DefineLexeme(0, true, LexicalRule.Chars(" \n\t\r").Repeat()); var number = lexb.DefineLexeme(1, digit.Repeat() + (LexicalRule.Char('.') + digit.Repeat() | LexicalRule.Empty)); var plus = lexb.DefineLexeme(2, LexicalRule.Char('+')); var minus = lexb.DefineLexeme(2, LexicalRule.Char('-')); var times = lexb.DefineLexeme(2, LexicalRule.Char('*')); var divide = lexb.DefineLexeme(2, LexicalRule.Char('/')); var bra = lexb.DefineLexeme(3, LexicalRule.Char('(')); var ket = lexb.DefineLexeme(3, LexicalRule.Char(')')); var plu = plus.GetParsingRule(); var min = minus.GetParsingRule(); var mul = times.GetParsingRule(); var div = divide.GetParsingRule(); var br = bra.GetParsingRule(); var ke = ket.GetParsingRule(); var num = number.GetParsingRule(i => double.Parse(i.Text)); ParsingRuleContainer <double> expr = new ParsingRuleContainer <double>(); ParsingRuleContainer <double> term = new ParsingRuleContainer <double>(); ParsingRuleContainer <double> factor = new ParsingRuleContainer <double>(); // ParsingRuleContainer<int, double> bracket = new ParsingRuleContainer<int, double>(); expr.Content = term.Concat((plu.Concat(term, (t, y) => y) | min.Concat(term, (t, y) => - y)).Repeat(i => i.Sum()), (x, y) => x + y) | term; term.Content = factor.Concat((mul.Concat(term, (s, y) => y) | (div.Concat(term, (s, y) => 1 / y))).Repeat(t => t.Count() == 0 ? 1 : t.Aggregate((x, y) => x * y)), (x, y) => x * y) | factor; factor.Content = br.Concat(expr, (s, x) => x).Concat(ke, (x, s) => x) | num; string str = "1 * 5 + 2 * 3 / 5 - 3"; BranchedLexer lexer = lexb.GetBranchedLexer(str); double r; expr.TryParse(lexer, out r); Assert.AreEqual(1.0 * 5.0 + 2.0 * 3.0 / 5.0 - 3.0, r); }
private void InitializeMemberParsers() { var modifier = lex_kw_public.GetParsingRule(t => Modifier.Public) | lex_kw_private.GetParsingRule(t => Modifier.Private) | lex_kw_protected.GetParsingRule(t => Modifier.Protected) | ParsingRule <Modifier> .Empty(Modifier.Public); var mem_modifier = lex_kw_static.GetParsingRule(t => true) .Concat(modifier, (t, u) => Tuple.Create(t, u)) | modifier .Concat(lex_kw_static.GetParsingRule(t => true) | ParsingRule <bool> .Empty(false), (u, t) => Tuple.Create(t, u)) | ParsingRule <Tuple <bool, Modifier> > .Empty(Tuple.Create(false, Modifier.Public)); var mem_field = (lex_op_assign.GetParsingRule() .Concat(p_expression.OrFail(ExceptionResource.ExpressionExpected), (t, e) => e) | PCE.Empty(null)) .Map(e => Tuple.Create(0, e, (ParameterCollection)null, (StatementCollection)null, (Tuple <Accessor, Accessor>)null)); var mem_method = p_paras .Concat(p_stats.OrFail(ExceptionResource.StatementsExpected), (t, stats) => Tuple.Create(1, (Expression)null, t, stats, (Tuple <Accessor, Accessor>)null)); var mem_constructor = lex_kw_constructor.GetParsingRule() .Concat(p_paras.OrFail(ExceptionResource.ParemetersExpected), (t, paras) => paras) .Concat(p_stats.OrFail(ExceptionResource.StatementsExpected), (t, stats) => Tuple.Create(2, (Expression)null, t, stats, (Tuple <Accessor, Accessor>)null)); var modifier1 = lex_kw_public.GetParsingRule(t => (Modifier?)Modifier.Public) | lex_kw_private.GetParsingRule(t => (Modifier?)Modifier.Private) | lex_kw_protected.GetParsingRule(t => (Modifier?)Modifier.Protected) | ParsingRule <Modifier?> .Empty(null); var getter = modifier1 .Concat(lex_kw_get.GetParsingRule(), (t, g) => Tuple.Create(t, g)) .Concat( lex_op_semicolon.GetParsingRule(t => (StatementCollection)null) | p_stats.OrFail(ExceptionResource.StatementsExpected), (t, stats) => new Accessor(t.Item2.LinePragma, t.Item1, stats)); var setter = modifier1 .Concat(lex_kw_set.GetParsingRule(), (t, g) => Tuple.Create(t, g)) .Concat( lex_op_semicolon.GetParsingRule(t => (StatementCollection)null) | p_stats.OrFail(ExceptionResource.StatementsExpected), (t, stats) => new Accessor(t.Item2.LinePragma, t.Item1, stats)); var prop_stats = getter.Concat(setter | ParsingRule <Accessor> .Empty(null), (g, s) => Tuple.Create(g, s)) | setter.Concat(getter | ParsingRule <Accessor> .Empty(null), (s, g) => Tuple.Create(g, s)); var mem_property = lex_op_leftBrace.GetParsingRule() .Concat(prop_stats, (t, s) => s) .Concat(lex_op_rightBrace.GetParsingRule().OrFailExpected("}"), (t, b) => t) .Map(t => { return(Tuple.Create(3, (Expression)null, (ParameterCollection)null, (StatementCollection)null, t)); }); ParsingRule <Tuple <int, Expression, ParameterCollection, StatementCollection, Tuple <Accessor, Accessor> > > mem_indexer = lex_kw_this.GetParsingRule() .Concat(lex_op_leftBracket.GetParsingRule(), (t, b) => t) .Concat(p_paraList, (t, p) => p) .Concat(lex_op_rightBracket.GetParsingRule().OrFailExpected("]"), (t, b) => t) .Concat(lex_op_leftBrace.GetParsingRule().OrFailExpected("{"), (t, b) => t) .Concat(prop_stats, (t, s) => Tuple.Create(t, s)) .Concat(lex_op_rightBrace.GetParsingRule().OrFailExpected("}"), (t, b) => t) .Map(t => { return(Tuple.Create(4, (Expression)null, t.Item1, (StatementCollection)null, t.Item2)); }); p_linePragma.Content = ParsingRuleContainer <LinePragma> .Custom(lexer => { var t = lexer.Peek(); if (t != null) { return(Tuple.Create(true, t.LinePragma)); } else { return(Tuple.Create(false, (LinePragma)null)); } }); p_member.Content = p_linePragma .Concat(mem_modifier, (t, m) => Tuple.Create(t, m)) .Concat( mem_constructor.Map((t) => Tuple.Create((Token)null, t)) | lex_identifer.GetParsingRule() .Concat(mem_method | mem_property | mem_field, (t, m) => Tuple.Create(t, m)) | mem_indexer.Map(t => Tuple.Create((Token)null, t)), (t, m) => { var lp = t.Item1; var mod = t.Item2; var type = m.Item2.Item1; var id = m.Item1; var exp = m.Item2.Item2; var para = m.Item2.Item3; var stat = m.Item2.Item4; var getset = m.Item2.Item5; if (type == 0) { return((Member) new Field(lp, mod.Item1, mod.Item2, id.Text, exp)); } else if (type == 1) { return((Member) new Method(lp, mod.Item1, mod.Item2, id.Text, para, stat)); } else if (type == 2) { return((Member) new Constructor(lp, mod.Item1, mod.Item2, para, stat)); } else if (type == 3) { var g = getset.Item1; var s = getset.Item2; return((Member) new Property(lp, mod.Item1, mod.Item2, id.Text, g, s)); } else if (type == 4) { var g = getset.Item1; var s = getset.Item2; return((Member) new Indexer(lp, mod.Item1, mod.Item2, para, g, s)); } else { throw new Exception(); } }); var member_semicolon = PM.Custom(lex => { Member m; if (p_member.TryParse(lex, out m)) { if (m is Field) { var t = lex.Peek(); if (t == null) { return(Tuple.Create(true, m)); } else if (t.Lexeme == lex_op_semicolon) { lex.Read(); return(Tuple.Create(true, m)); } else if (t.Lexeme == lex_op_rightBrace) { return(Tuple.Create(true, m)); } else if (t.LinePragma.Line > m.LinePragma.Line) { return(Tuple.Create(true, m)); } else { Util.Fail <Member>(string.Format(ExceptionResource.Expected, ";")).TryParse(lex, out m); } } else { return(Tuple.Create(true, m)); } } return(Tuple.Create(false, (Member)null)); }); p_members.Content = member_semicolon.Repeat(i => new MemberCollection(i)); }