Example #1
0
        public static LNode LLLPG_lexer(LNode node, IMacroContext context)
        {
            return(LllpgMacro(node, context, _lexer, lexerCfg =>
            {
                var helper = new IntStreamCodeGenHelper();
                foreach (var option in MacroContext.GetOptions(lexerCfg.Args))
                {
                    LNode value = option.Value ?? LNode.Missing;
                    string key = option.Key.Name.Name;
                    switch (key.ToLowerInvariant())
                    {
                    case "inputsource":      helper.InputSource = value; break;

                    case "inputclass":       helper.InputClass = value; break;

                    case "terminaltype":     helper.TerminalType = value; break;

                    case "settype":          helper.SetType = value; break;

                    case "listinitializer":  helper.SetListInitializer(value); break;

                    case "nocheckbydefault": SetOption <bool>(context, option.Key, value.Value, b => helper.NoCheckByDefault = b); break;

                    default:
                        context.Sink.Error(option.Key, "Unrecognized option '{0}'. Available options: " +
                                           "InputSource: var, InputClass: type, TerminalType: type, SetType: type, " +
                                           "ListInitializer: var _ = new List<T>(), NoCheckByDefault: true", key);
                        break;
                    }
                }
                return helper;
            }));
        }
Example #2
0
        public static LNode LLLPG_lexer(LNode node, IMacroContext context)
        {
            return(LllpgMacro(node, context, _lexer, lexerCfg =>
            {
                var helper = new IntStreamCodeGenHelper();
                foreach (var option in MacroContext.GetOptions(lexerCfg.Args))
                {
                    LNode value = option.Value;
                    string key = (option.Key ?? (Symbol)"??").Name;
                    switch (key.ToLowerInvariant())
                    {
                    case "inputsource": helper.InputSource = value; break;

                    case "inputclass": helper.InputClass = value; break;

                    case "terminaltype": helper.TerminalType = value; break;

                    case "settype": helper.SetType = value; break;

                    case "listinitializer": helper.SetListInitializer(value); break;

                    default:
                        context.Write(Severity.Error, value, "Unrecognized option '{0}'. Available options: " +
                                      "inputSource: var, inputClass: type, terminalType: type, setType: type, listInitializer: var _ = new List<T>()", key);
                        break;
                    }
                }
                return helper;
            }));
        }
Example #3
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;
                }
            }
        }
Example #4
0
        public static LNode LLLPG_parser(LNode node, IMacroContext context)
        {
            return(LllpgMacro(node, context, _parser, parserCfg => {
                // Scan options in parser(...) node
                var helper = new GeneralCodeGenHelper();
                if (parserCfg == null)
                {
                    return helper;
                }
                foreach (var option in MacroContext.GetOptions(parserCfg.Args))
                {
                    LNode value = option.Value ?? LNode.Missing;
                    string key = option.Key.Name.Name;
                    switch (key.ToLowerInvariant())
                    {
                    case "inputsource":     helper.InputSource = value; break;

                    case "inputclass":      helper.InputClass = value; break;

                    case "terminaltype":    helper.TerminalType = value; break;

                    case "settype":         helper.SetType = value;   break;

                    case "listinitializer": helper.SetListInitializer(value); break;

                    case "nocheckbydefault": SetOption <bool>(context, option.Key, value.Value, b => helper.NoCheckByDefault = b); break;

                    case "allowswitch":     SetOption <bool>(context, option.Key, value.Value, b => helper.AllowSwitch = b); break;

                    case "castla":          SetOption <bool>(context, option.Key, value.Value, b => helper.CastLA = b); break;

                    case "latype":          helper.LaType = value;    break;

                    case "matchtype":                                   // alternate name
                    case "matchcast":       helper.MatchCast = value; break;

                    default:
                        context.Sink.Error(option.Key, "Unrecognized option '{0}'. Available options: " +
                                           "InputSource: variable, InputClass: type, TerminalType: type, SetType: type, " +
                                           "ListInitializer: var _ = new List<T>(), NoCheckByDefault: true, AllowSwitch: bool, " +
                                           "CastLA: bool, LAType: type, MatchCast: type", key);
                        break;
                    }
                }
                return helper;
            }, isDefault: true));
        }
Example #5
0
        public static LNode LLLPG_lexer(LNode node, IMacroContext context)
        {
            var   p    = context.GetArgsAndBody(true);
            var   args = p.A;
            var   body = p.B;
            LNode lexerCfg;

            if (args.Count != 1 || (lexerCfg = args[0]).Name != _lexer)
            {
                return(null);
            }

            // Scan options in lexer(...) node
            var helper = new IntStreamCodeGenHelper();

            foreach (var option in MacroContext.GetOptions(lexerCfg.Args))
            {
                LNode  value = option.Value;
                string key   = (option.Key ?? (Symbol)"??").Name;
                switch (key.ToLowerInvariant())
                {
                case "inputsource":     helper.InputSource = value; break;

                case "inputclass":      helper.InputClass = value; break;

                case "terminaltype":    helper.TerminalType = value; break;

                case "settype":         helper.SetType = value; break;

                case "listinitializer": helper.SetListInitializer(value); break;

                default:
                    context.Write(Severity.Error, value, "Unrecognized option '{0}'. Available options: " +
                                  "inputSource: var, inputClass: type, terminalType: type, setType: type, listInitializer: var _ = new List<T>()", key);
                    break;
                }
            }

            return(node.WithTarget(_run_LLLPG).WithArgs(F.Literal(helper), F.Braces(body)));
        }
Example #6
0
        public static LNode LLLPG_parser(LNode node, IMacroContext context)
        {
            var   p         = context.GetArgsAndBody(true);
            var   args      = p.A;
            var   body      = p.B;
            LNode parserCfg = null;

            if (args.Count > 0)
            {
                if ((parserCfg = args[0]).Name != _parser || args.Count > 1)
                {
                    return(null);
                }
            }

            // Scan options in parser(...) node
            var helper = new GeneralCodeGenHelper();

            if (parserCfg != null)
            {
                foreach (var option in MacroContext.GetOptions(parserCfg.Args))
                {
                    LNode  value = option.Value;
                    string key   = (option.Key ?? (Symbol)"??").Name;
                    switch (key.ToLowerInvariant())
                    {
                    case "inputsource": helper.InputSource = value; break;

                    case "inputclass":  helper.InputClass = value; break;

                    case "terminaltype": helper.TerminalType = value; break;

                    case "latype":      helper.LaType = value;    break;

                    case "matchtype":                               // alternate name
                    case "matchcast":   helper.MatchCast = value; break;

                    case "settype":     helper.SetType = value;   break;

                    case "allowswitch":
                        if (value.Value is bool)
                        {
                            helper.AllowSwitch = (bool)value.Value;
                        }
                        else
                        {
                            context.Write(Severity.Error, value, "AllowSwitch: expected literal boolean argument.");
                        }
                        break;

                    case "castla":
                        if (value.Value is bool)
                        {
                            helper.CastLA = (bool)value.Value;
                        }
                        else
                        {
                            context.Write(Severity.Error, value, "CastLA: expected literal boolean argument.");
                        }
                        break;

                    case "listinitializer":
                        helper.SetListInitializer(value);
                        break;

                    default:
                        context.Write(Severity.Error, value, "Unrecognized option '{0}'. Available options: " +
                                      "inputSource: variable, inputClass: type, terminalType: type, laType: type, matchCast: type, setType: type, allowSwitch: bool, castLa: bool, listInitializer: var _ = new List<T>()", key);
                        break;
                    }
                }
            }

            return(node.WithTarget(_run_LLLPG).WithArgs(F.Literal(helper), F.Braces(body)));
        }
Example #7
0
        public static LNodeList UseSymbolsCore(LNodeList symbolAttrs, LNodeList options, LNodeList body, IMacroContext context, bool inType)
        {
            // Decode options (TODO: invent a simpler approach)
            string prefix    = "sy_";
            var    inherited = new HashSet <Symbol>();

            foreach (var pair in MacroContext.GetOptions(options))
            {
                if (pair.Key.Name.Name == "prefix" && pair.Value.IsId)
                {
                    prefix = pair.Value.Name.Name;
                }
                else if (pair.Key.Name.Name == "inherit" && pair.Value.Value is Symbol)
                {
                    inherited.Add((Symbol)pair.Value.Value);
                }
                else if (pair.Key.Name.Name == "inherit" && (pair.Value.Calls(S.Braces) || pair.Value.Calls(S.Tuple)) && pair.Value.Args.All(n => n.Value is Symbol))
                {
                    foreach (var arg in pair.Value.Args)
                    {
                        inherited.Add((Symbol)arg.Value);
                    }
                }
                else
                {
                    context.Sink.Warning(pair.Key, "Unrecognized parameter. Expected prefix:id or inherit:{@@A; @@B; ...})");
                }
            }

            // Replace all symbols while collecting a list of them
            var       symbols = new Dictionary <Symbol, LNode>();
            LNodeList output  = body.SmartSelect(stmt =>
                                                 stmt.ReplaceRecursive(n => {
                if (!inType && n.ArgCount == 3)
                {
                    // Since we're outside any type, we must avoid creating symbol
                    // fields. When we cross into a type then we can start making
                    // Symbols by calling ourself recursively with inType=true
                    var kind = EcsValidators.SpaceDefinitionKind(n);
                    if (kind == S.Class || kind == S.Struct || kind == S.Interface || kind == S.Alias || kind == S.Trait)
                    {
                        var body2 = n.Args[2];
                        return(n.WithArgChanged(2, body2.WithArgs(UseSymbolsCore(symbolAttrs, options, body2.Args, context, true))));
                    }
                }
                var sym = n.Value as Symbol;
                if (n.IsLiteral && sym != null)
                {
                    return(symbols[sym] = LNode.Id(prefix + sym.Name));
                }
                return(null);
            })
                                                 );

            // Return updated code with variable declaration at the top for all non-inherit symbols used.
            var _Symbol = F.Id("Symbol");
            var vars    = (from sym in symbols
                           where !inherited.Contains(sym.Key)
                           select F.Call(S.Assign, sym.Value,
                                         F.Call(S.Cast, F.Literal(sym.Key.Name), _Symbol))).ToList();

            if (vars.Count > 0)
            {
                output.Insert(0, F.Call(S.Var, ListExt.Single(_Symbol).Concat(vars))
                              .WithAttrs(symbolAttrs.Add(F.Id(S.Static)).Add(F.Id(S.Readonly))));
            }
            return(output);
        }
Example #8
0
        public static LNode LLLPG_parser(LNode node, IMacroContext context)
        {
            return(LllpgMacro(node, context, _parser, parserCfg => {
                // Scan options in parser(...) node
                var helper = new GeneralCodeGenHelper();
                if (parserCfg == null)
                {
                    return helper;
                }
                foreach (var option in MacroContext.GetOptions(parserCfg.Args))
                {
                    LNode value = option.Value;
                    string key = (option.Key ?? (Symbol)"??").Name;
                    switch (key.ToLowerInvariant())
                    {
                    case "inputsource": helper.InputSource = value; break;

                    case "inputclass":  helper.InputClass = value; break;

                    case "terminaltype": helper.TerminalType = value; break;

                    case "settype":     helper.SetType = value;   break;

                    case "listinitializer": helper.SetListInitializer(value); break;

                    case "latype":      helper.LaType = value;    break;

                    case "matchtype":                               // alternate name
                    case "matchcast":   helper.MatchCast = value; break;

                    case "allowswitch":
                        if (value.Value is bool)
                        {
                            helper.AllowSwitch = (bool)value.Value;
                        }
                        else
                        {
                            context.Write(Severity.Error, value, "AllowSwitch: expected literal boolean argument.");
                        }
                        break;

                    case "castla":
                        if (value.Value is bool)
                        {
                            helper.CastLA = (bool)value.Value;
                        }
                        else
                        {
                            context.Write(Severity.Error, value, "CastLA: expected literal boolean argument.");
                        }
                        break;

                    default:
                        context.Write(Severity.Error, value, "Unrecognized option '{0}'. Available options: " +
                                      "inputSource: variable, inputClass: type, terminalType: type, laType: type, matchCast: type, setType: type, allowSwitch: bool, castLa: bool, listInitializer: var _ = new List<T>()", key);
                        break;
                    }
                }
                return helper;
            }, isDefault: true));
        }