Esempio n. 1
0
        void GenerateCondPost(TextWriter tw, AST.Cond node, int n, bool match_args, string indent)
        {
            string condition = TrimBraces(node.GetText().Trim()).Trim();
            condition = condition.Replace("\t", "    ");

            tw.Write(indent); tw.WriteLine("// COND");

            string index = match_args ? "_arg_index" : "_index";
            string results = match_args ? "_memo.ArgResults" : "_memo.Results";

            if (condition.Contains("return") || condition.Contains("_IM_Result"))
            {
                if (!condition.Contains("return"))
                    condition = "return " + condition;
                if (!condition.EndsWith(";"))
                    condition = condition + ";";

                tw.Write(indent); tw.WriteLine("Func<{2}, bool> lambda{0} = (_IM_Result) => {{ {1} }};", n, condition, tItem);
                tw.Write(indent); tw.WriteLine("if ({1}.Peek() == null || !lambda{0}({1}.Peek())) {{ {1}.Pop(); {1}.Push(null); {2} = _start_i{0}; }}", n, results, index);
            }
            else
            {
                tw.Write(indent); tw.WriteLine("if ({2}.Peek() == null || !({1})) {{ {2}.Pop(); {2}.Push(null); {3} = _start_i{0}; }}", n, condition, results, index);
            }

            tw.WriteLine();
        }
Esempio n. 2
0
        void GenerateLiteralPost(TextWriter tw, AST.Code node, int n, bool match_args, string indent)
        {
            string literal = TrimBraces(node.GetText().Trim()).Trim();

            tw.Write(indent); tw.WriteLine("// LITERAL {0}", literal);

            if (match_args)
            {
                tw.Write(indent); tw.WriteLine("_ParseLiteralArgs(_memo, ref _arg_index, ref _arg_input_index, {0}, _args);", literal);
            }
            else
            {
                bool isCharMatcher = tInput == "char" || tInput.EndsWith("Character");

                tw.Write(indent);
                if (isCharMatcher && literal.StartsWith("\""))
                    tw.WriteLine("_ParseLiteralString(_memo, ref _index, {0});", literal);
                else if (isCharMatcher && literal.StartsWith("'"))
                    tw.WriteLine("_ParseLiteralChar(_memo, ref _index, {0});", literal);
                else
                    tw.WriteLine("_ParseLiteralObj(_memo, ref _index, {0});", literal);
            }

            tw.WriteLine();
        }
Esempio n. 3
0
        void GenerateRegexpPost(TextWriter tw, AST.Regexp node, int n, bool match_args, string indent)
        {
            bool isCharMatcher = tInput == "char" || tInput.EndsWith("Character");
            if (!isCharMatcher) throw new Exception("Can only use regular expressions when matching characters.");
            if (match_args) throw new Exception("Cannot use a regular expression in rule arguments.");

            var text = node.GetText().Trim(' ', '/');
            string name;

            if (!regexps.TryGetValue(text, out name))
            {
                name = string.Format("_re{0}", regexps.Count);
                regexps.Add(text, name);
            }

            tw.Write(indent); tw.WriteLine("// REGEXP {0}", text);
            tw.Write(indent); tw.WriteLine("_ParseRegexp(_memo, ref _index, {0});", name);
            tw.WriteLine();
        }
Esempio n. 4
0
        void Analyze(AST.AstNode node, AST.Rule currentRule)
        {
            // get grammar name & generic parameters
            if (node is AST.Grammar)
            {
                AST.Grammar gr = node as AST.Grammar;
                tInput = gr.GetText(gr.TInput).Trim();
                tResult = gr.GetText(gr.TResult).Trim();
                gName = gr.GetText(gr.Name).Trim();
                tItem = string.Format("_{0}_Item", gName);
                gBase = gr.GetText(gr.Base).Trim();
                if (string.IsNullOrWhiteSpace(gBase))
                    gBase = string.Format("IronMeta.Matcher.Matcher<{0}, {1}>", tInput, tResult);
            }

            // also analyze arguments (because they are not children)
            else if (node is AST.Args)
            {
                AST.Args args = node as AST.Args;
                if (args.Parms != null)
                    Analyze(args.Parms, currentRule);
            }

            // collect rule bodies
            else if (node is AST.Rule)
            {
                currentRule = node as AST.Rule;
                ruleNodes.Add(currentRule);

                string ruleName = node.GetText().Trim();

                if (!string.IsNullOrEmpty(currentRule.Override))
                    overrides[ruleName] = currentRule.Override;

                AST.AstNode oldBody;
                if (ruleBodies.TryGetValue(ruleName, out oldBody))
                    ruleBodies[ruleName] = new AST.Or(oldBody, currentRule.Body);
                else
                    ruleBodies.Add(ruleName, currentRule.Body);
            }

            // collect input classes
            else if (node is AST.InputClass)
            {
                AST.InputClass input = node as AST.InputClass;

                foreach (AST.AstNode child in input.Inputs)
                {
                    if (child is AST.Code)
                    {
                        input.Chars.Add(TrimBraces(child.GetText().Trim()).Trim());
                    }
                    else if (child is AST.ClassRange)
                    {
                        foreach (char ch in ((AST.ClassRange)child).Inputs)
                        {
                            input.Chars.Add(string.Format("'\\u{0:x4}'", (int)ch));
                        }
                    }
                }
            }

            // hoist rule bodies inside calls
            else if (node is AST.Call)
            {
                HoistCalledDisjunctions(currentRule, node as AST.Call);
            }

            // recurse
            if (node.Children != null)
            {
                foreach (AST.AstNode child in node.Children)
                {
                    if (child != null)
                        Analyze(child, currentRule);
                }
            }
        }
Esempio n. 5
0
        void GenerateBindPost(TextWriter tw, HashSet<string> vars, AST.Bind node, int n, bool match_args, string indent)
        {
            string name = node.GetText().Trim();

            tw.Write(indent); tw.WriteLine("// BIND {0}", name);
            tw.Write(indent);

            if (match_args)
                tw.WriteLine("{0} = _memo.ArgResults.Peek();", name);
            else
                tw.WriteLine("{0} = _memo.Results.Peek();", name);
            tw.WriteLine();

            vars.Add(name);
        }
Esempio n. 6
0
        void GenerateActPost(TextWriter tw, AST.Act node, int n, bool match_args, string indent)
        {
            string action = TrimBraces(node.GetText().Trim()).Trim();
            action = action.Replace("\t", "    ");

            if (!action.Contains("return"))
                action = "return " + action + ";";

            tw.Write(indent); tw.WriteLine("// ACT");

            if (match_args)
            {
                tw.Write(indent); tw.WriteLine("var _r{0} = _memo.ArgResults.Peek();", n);
                tw.Write(indent); tw.WriteLine("if (_r{0} != null)", n);
                tw.Write(indent); tw.WriteLine("{");
                tw.Write(indent); tw.WriteLine("    _memo.ArgResults.Pop();");
                tw.Write(indent); tw.WriteLine("    _memo.ArgResults.Push( new {1}(_r{0}.StartIndex, _r{0}.NextIndex, _r{0}.Inputs, _Thunk(_IM_Result => {{ {2} }}, _r{0}), false) );", n, tItem, action);
                tw.Write(indent); tw.WriteLine("}");
            }
            else
            {
                tw.Write(indent); tw.WriteLine("var _r{0} = _memo.Results.Peek();", n);
                tw.Write(indent); tw.WriteLine("if (_r{0} != null)", n);
                tw.Write(indent); tw.WriteLine("{");
                tw.Write(indent); tw.WriteLine("    _memo.Results.Pop();");
                tw.Write(indent); tw.WriteLine("    _memo.Results.Push( new {2}(_r{0}.StartIndex, _r{0}.NextIndex, _memo.InputEnumerable, _Thunk(_IM_Result => {{ {1} }}, _r{0}), true) );", n, action, tItem);
                tw.Write(indent); tw.WriteLine("}");
            }

            tw.WriteLine();
        }
Esempio n. 7
0
        void GenerateCallPost(TextWriter tw, HashSet<string> vars, AST.Call node, int n, bool match_args, string indent)
        {
            string name = node.GetText().Trim();

            tw.Write(indent); tw.WriteLine("// CALL {0}", name);

            if (match_args)
            {
                throw new Exception(string.Format("{0}: you are not allowed to call rules in argument patterns.", name));
            }
            else
            {
                tw.Write(indent); tw.WriteLine("var _start_i{0} = _index;", n);
                tw.Write(indent); tw.WriteLine("{1} _r{0};", n, tItem);

                bool isVar = vars.Contains(name);

                if (node.Params != null && node.Params.Any())
                {
                    List<string> plist = GenerateActualParams(tw, vars, node, n, name, indent);

                    tw.WriteLine();
                    tw.Write(indent); tw.WriteLine("_r{3} = _MemoCall(_memo, {0}, _index, {4}, new {2}[] {{ {1} }});",
                        isVar ? name + ".ProductionName" : "\"" + name + "\"",
                        string.Join(", ", plist.ToArray()),
                        tItem,
                        n,
                        isVar ? name + ".Production" : name);
                }
                else
                {
                    tw.Write(indent); tw.WriteLine("_r{1} = _MemoCall(_memo, {0}, _index, {2}, null);",
                        isVar ? name + ".ProductionName" : "\"" + name + "\"",
                        n,
                        isVar ? name + ".Production" : name);
                }

                tw.WriteLine();
                tw.Write(indent); tw.WriteLine("if (_r{0} != null) _index = _r{0}.NextIndex;", n);
                tw.WriteLine();

            }
        }
Esempio n. 8
0
        void GenerateCallOrVarPost(TextWriter tw, HashSet<string> vars, AST.CallOrVar node, int n, bool match_args, string indent)
        {
            string name = node.GetText().Trim();

            tw.Write(indent); tw.WriteLine("// CALLORVAR {0}", name);

            if (match_args)
            {
                if (vars.Contains(name))
                {
                    tw.Write(indent); tw.WriteLine("var _r{0} = _ParseLiteralArgs(_memo, ref _arg_index, ref _arg_input_index, {1}.Inputs, _args);", n, name);
                    tw.Write(indent); tw.WriteLine("if (_r{0} != null) _arg_index = _r{0}.NextIndex;", n);
                }
                else
                {
                    throw new Exception(string.Format("{0}: you are not allowed to call rules in argument patterns.", name));
                }
            }
            else
            {
                tw.Write(indent); tw.WriteLine("{1} _r{0};", n, tItem);
                tw.WriteLine();

                if (vars.Contains(name))
                {
                    tw.Write(indent); tw.WriteLine("if ({0}.Production != null)", name);
                    tw.Write(indent); tw.WriteLine("{");
                    tw.Write(indent); tw.WriteLine("    var _p{0} = (System.Action<_{3}_Memo, int, IEnumerable<{1}>>)(object){2}.Production; // what type safety?", n, tItem, name, gName);
                    tw.Write(indent); tw.WriteLine("    _r{0} = _MemoCall(_memo, RuntimeReflectionExtensions.GetMethodInfo({1}.Production).Name, _index, _p{0}, null);", n, name);
                    tw.Write(indent); tw.WriteLine("}");
                    tw.Write(indent); tw.WriteLine("else");
                    tw.Write(indent); tw.WriteLine("{");
                    tw.Write(indent); tw.WriteLine("    _r{0} = _ParseLiteralObj(_memo, ref _index, {1}.Inputs);", n, name);
                    tw.Write(indent); tw.WriteLine("}");
                }
                else
                {
                    tw.Write(indent); tw.WriteLine("_r{1} = _MemoCall(_memo, \"{0}\", _index, {0}, null);", name, n);
                }

                tw.WriteLine();
                tw.Write(indent); tw.WriteLine("if (_r{0} != null) _index = _r{0}.NextIndex;", n);
            }

            tw.WriteLine();
        }