Beispiel #1
0
        public LNode GenerateParserCode()
        {
            _pg = new LLParserGenerator(new GeneralCodeGenHelper(F.Id("TT"), true)
            {
                MatchType = F.Int32
            }, MessageSink.Console);

            // Just do whitespace-agnostic LES at first

#if false
            int *$
            int?$
            int[]
Beispiel #2
0
        private static void ApplyOptions(LNode node, LLParserGenerator lllpg, IMacroContext sink, IEnumerable <Rule> rules)
        {
            foreach (var pair in MacroContext.GetOptions(node.Attrs))
            {
                LNode  key   = pair.Key;
                object value = pair.Value != null ? pair.Value.Value : null;
                switch (key.Name.Name)
                {
                case "FullLLk":
                    SetOption <bool>(sink, key, value ?? G.BoxedTrue, v => lllpg.FullLLk = v);
                    break;

                case "Verbosity":
                    SetOption <int>(sink, key, value, v => lllpg.Verbosity = v);
                    break;

                case "NoDefaultArm":
                    SetOption <bool>(sink, key, value ?? G.BoxedTrue, v => lllpg.NoDefaultArm = v);
                    break;

                case "LL":
                case "DefaultK":
                case "k":
                case "K":                                                               // [LL(k)] is preferred
                    SetOption <int>(sink, key, value, v => lllpg.DefaultK = v);
                    break;

                case "AddComments":
                    SetOption <bool>(sink, key, value ?? G.BoxedTrue, v => lllpg.AddComments = v);
                    break;

                case "AddCsLineDirectives":
                    SetOption <bool>(sink, key, value ?? G.BoxedTrue, v => lllpg.AddCsLineDirectives = v);
                    break;

                case "PrematchByDefault":
                    SetOption <bool>(sink, key, value ?? G.BoxedTrue, v => lllpg.PrematchByDefault = v);
                    break;

                default:
                    if (!key.IsTrivia)
                    {
                        sink.Error(key,
                                   "Unrecognized attribute. LLLPG supports the following options: " +
                                   "FullLLk(bool), Verbosity(0..3), NoDefaultArm(bool), DefaultK(1..9), AddComments(bool), AddCsLineDirectives(bool), and PrematchByDefault(bool)");
                    }
                    break;
                }
            }
        }
Beispiel #3
0
        private static void ApplyOptions(LNode node, LLParserGenerator lllpg, IMessageSink sink)
        {
            for (int i = 0; i < node.Attrs.Count; i++)
            {
                var attr = node.Attrs[i];
                switch (attr.Name.Name)
                {
                case "FullLLk":
                    ReadOption <bool>(sink, attr, v => lllpg.FullLLk = v, true);
                    break;

                case "Verbosity":
                    ReadOption <int>(sink, attr, v => lllpg.Verbosity = v, null);
                    break;

                case "NoDefaultArm":
                    ReadOption <bool>(sink, attr, v => lllpg.NoDefaultArm = v, true);
                    break;

                case "DefaultK":
                case "k":
                case "K":
                case "LL":
                    ReadOption <int>(sink, attr, v => lllpg.DefaultK = v, null);
                    break;

                case "AddComments":
                    ReadOption <bool>(sink, attr, v => lllpg.AddComments = v, true);
                    break;

                case "AddCsLineDirectives":
                    ReadOption <bool>(sink, attr, v => lllpg.AddCsLineDirectives = v, true);
                    break;

                default:
                    sink.Write(Severity.Error, attr,
                               "Unrecognized attribute. LLLPG supports the following options: " +
                               "FullLLk(bool), Verbosity(0..3), NoDefaultArm(bool), DefaultK(1..9), AddComments(bool), and AddCsLineDirectives(bool)");
                    break;
                }
            }
        }
Beispiel #4
0
			public GenerateCodeVisitor(LLParserGenerator llpg)
			{
				LLPG = llpg;
				F = new LNodeFactory(llpg._sourceFile);
				_classBody = llpg._classBody;
			}
Beispiel #5
0
		public void SetUp()
		{
			LNode.Printer = EcsNodePrinter.Printer;
			_pg = new LLParserGenerator(new IntStreamCodeGenHelper());
			_pg.Sink = new MessageSinkFromDelegate(OutputMessage);
			_messageCounter = 0;
			_expectingOutput = false;
			_file = new EmptySourceFile("LlpgTests.cs");
		}
Beispiel #6
0
        public static LNode run_LLLPG(LNode node, IMacroContext context)
        {
            node = context.PreProcessChildren();

            IPGCodeGenHelper helper;
            LNode            body;
            bool             hasBraces = true;

            if (node.ArgCount != 2 ||
                (helper = node.Args[0].Value as IPGCodeGenHelper) == null ||
                !(hasBraces = (body = node.Args[1]).Calls(S.Braces)))
            {
                string msg = Localize.Localized("Expected run_LLLPG(helper_object, {...}).");
                if (hasBraces)
                {
                    msg = " " + Localize.Localized("An auxiliary macro is required to supply the helper object.");
                }
                context.Write(Severity.Note, node, msg);
                return(null);
            }
            helper = helper ?? new GeneralCodeGenHelper();

            var rules = new List <Pair <Rule, LNode> >();
            var stmts = new List <LNode>();

            // Let helper preprocess the code if it wants to
            foreach (var stmt in body.Args)
            {
                var stmt2 = helper.VisitInput(stmt, context) ?? stmt;
                if (stmt2.Calls(S.Splice))
                {
                    stmts.AddRange(stmt2.Args);
                }
                else
                {
                    stmts.Add(stmt2);
                }
            }

            // Find rule definitions, create Rule objects
            for (int i = 0; i < stmts.Count; i++)
            {
                LNode stmt = stmts[i];
                bool  isToken;
                if ((isToken = stmt.Calls(_hash_token, 4)) || stmt.Calls(_hash_rule, 4))
                {
                    LNode basis      = stmt.WithTarget(S.Fn);
                    LNode methodBody = stmt.Args.Last;

                    // basis has the form #fn(ReturnType, Name, #(Args))
                    var rule = MakeRuleObject(isToken, ref basis, context);
                    if (rule != null)
                    {
                        var prev = rules.FirstOrDefault(pair => pair.A.Name == rule.Name);
                        if (prev.A != null)
                        {
                            context.Sink.Error(rule.Basis, "The rule name «{0}» was used before at {1}", rule.Name, prev.A.Basis.Range.Start);
                        }
                        else
                        {
                            rules.Add(Pair.Create(rule, methodBody));
                        }

                        stmts[i] = null;                         // remove processed rules from the list
                    }
                }
                else
                {
                    if (stmt.Calls(_rule) || stmt.Calls(_token))
                    {
                        context.Sink.Error(stmt, "A rule should have the form rule(Name(Args)::ReturnType, @{...})");
                    }
                }
            }

            if (rules.Count == 0)
            {
                context.Sink.Warning(node, "No grammar rules were found in LLLPG block");
            }

            // Parse the rule definitions (now that we know the names of all the
            // rules, we can decide if an Id refers to a rule; if not, it's assumed
            // to refer to a terminal).
            new StageTwoParser(helper, context).Parse(rules);

            // Process the grammar & generate code
            var lllpg = new LLParserGenerator(helper, context);

            ApplyOptions(node, lllpg, context, rules.Select(p => p.Key));             // Read attributes such as [DefaultK(3)]
            foreach (var pair in rules)
            {
                lllpg.AddRule(pair.A);
            }

            // TODO: change lllpg so we can interleave generated code with other
            // user code, to preserve the order of declarations in the original code.
            var results = lllpg.Run(node.Source);

            return(F.Call(S.Splice, stmts.Where(p => p != null).Concat(results.Args)));
        }
Beispiel #7
0
				int _ruleDepth = 0; // Used to avoid stack overflow, which crashes VS in SFG
				public ApplyPrematchVisitor(LLParserGenerator llpg) { LLPG = llpg; }
Beispiel #8
0
			public PrematchAnalysisVisitor(LLParserGenerator llpg) 
			{
				LLPG = llpg;
				Anything = LLPG.CodeGenHelper.EmptySet.Inverted();
				_apply = new ApplyPrematchVisitor(llpg);
			}
Beispiel #9
0
			public PredictionAnalysisVisitor(LLParserGenerator llpg) { LLPG = llpg; }