Ejemplo n.º 1
0
        //Adds a single context to the grammar string.
        private void AddContext(IroContext ctx, IroPrecompileData data, ref PyStringMaker text)
        {
            //Open the context.
            text.AppendLine("'" + ctx.Name + "' : [");
            text.TabIn();

            //Add context members.
            foreach (var member in ctx.Members)
            {
                AddContextMember(ctx.Name, member, data, ref text);
            }
            text.TrimEnd(',', ' ');

            text.TabOut();
            text.AppendLine("],");
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Compiles pre-compile data into a Pygments grammar file.
        /// </summary>
        public CompileResult Compile(IroPrecompileData data)
        {
            var text = new PyStringMaker();

            //Header for imports and class naming.
            text.AppendLine("from pygments.lexer import RegexLexer, bygroups");
            text.AppendLine("from pygments.token import *");
            text.AppendLine("import re");
            text.AppendLine("__all__ =['" + data.Name + "Lexer']");
            text.AppendLine();
            text.AppendLine("class " + data.Name + "Lexer(RegexLexer):");
            text.TabIn();

            //Name with capital first letter, aliases.
            text.AppendLine("name = '" + data.Name[0].ToString().ToUpper() + data.Name.Substring(1) + "'");
            text.AppendLine("aliases = ['" + data.Name + "']");

            //File names.
            string fNames = "[";

            foreach (var ext in data.FileExtensions)
            {
                fNames += "'" + ext + "', ";
            }
            fNames = fNames.TrimEnd(',', ' ') + "]";
            text.AppendLine(fNames);

            //Template flags.
            text.AppendLine("flags = re.MULTILINE | re.UNICODE");
            text.AppendLine();

            //Open the tokens map.
            text.AppendLine("tokens = {");
            text.TabIn();

            //Get the root context and evaluate.
            var rootCtx = data.Contexts.FirstOrDefault(x => x.Name == "main");

            if (rootCtx == null)
            {
                Error.Compile("No 'main' context exists to create the root grammar state from.");
                return(null);
            }
            AddContext(rootCtx, data, ref text);
            includedThisRun = new List <string>();

            //Evaluate the rest of the contexts.
            foreach (var context in data.Contexts)
            {
                //Ignore main, already done.
                if (context.Name == "main")
                {
                    continue;
                }

                //Add, reset includes.
                AddContext(context, data, ref text);
                includedThisRun = new List <string>();
            }

            //Add queued contexts.
            for (int i = 0; i < queuedContexts.Count; i++)
            {
                var queued = queuedContexts.ElementAt(i);
                AddQueuedContext(queued.Key.Item2, queued.Key.Item1, queued.Value, data, ref text);
            }

            text.TabOut();
            text.AppendLine("}");

            return(new CompileResult()
            {
                GeneratedFile = text.ToString(),
                Target = Target.Pygments
            });
        }
Ejemplo n.º 3
0
        //Adds a queued context to the text.
        private void AddQueuedContext(string name, string originalCtx, InlinePushContextMember ilp, IroPrecompileData data, ref PyStringMaker text)
        {
            //Open the context.
            text.AppendLine("'" + name + "' : [");
            text.TabIn();

            //Add the pop rule.
            var popStyles = GetPatternStyles(ilp.PopStyles, data);

            text.AppendLine("(u'" + ilp.PopData.Replace("\\", "\\\\") + "', byGroups(" + string.Join(", ", popStyles.Select(x => x.PygmentsScope)).TrimEnd(',', ' ') + "), '" + originalCtx + "')");

            //Add context members.
            includedThisRun = new List <string>();
            foreach (var member in ilp.Patterns)
            {
                AddContextMember(name, member, data, ref text);
            }
            text.TrimEnd(',', ' ');

            text.TabOut();
            text.AppendLine("],");
        }
Ejemplo n.º 4
0
        private void AddContextMember(string ctxName, ContextMember member, IroPrecompileData data, ref PyStringMaker text)
        {
            //What's the context member type?
            string regTxt = "";

            switch (member.Type)
            {
            //Normal pattern.
            case ContextMemberType.Pattern:
                var pat = (PatternContextMember)member;
                regTxt += "(u'" + pat.Data.Replace("\\", "\\\\") + "', bygroups(";

                //Get styles out.
                var styles = GetPatternStyles(pat.Styles, data);

                //Apply styles.
                foreach (var style in styles)
                {
                    regTxt += style.PygmentsScope + ", ";
                }
                regTxt = regTxt.TrimEnd(',', ' ');

                //Close bygroups, end pattern.
                regTxt += ")),";
                text.AppendLine(regTxt);
                return;

            //Inline push.
            case ContextMemberType.InlinePush:
                var ilp = (InlinePushContextMember)member;
                regTxt += "(u'" + ilp.Data.Replace("\\", "\\\\") + "', bygroups(";

                //Get push styles out.
                var pushStyles = GetPatternStyles(ilp.Styles, data);

                //Add and close bygroups scope.
                foreach (var style in pushStyles)
                {
                    regTxt += style.PygmentsScope + ", ";
                }
                regTxt  = regTxt.TrimEnd(',', ' ');
                regTxt += ")";

                //Add the push scope with a random name.
                string helperName = "helper_" + ShortId.Generate(7);
                QueueContext(ctxName, helperName, ilp);
                regTxt += ", '" + helperName + "'),";

                text.AppendLine(regTxt);
                return;

            //Include.
            case ContextMemberType.Include:
                //Get the context to include.
                var ctx = data.Contexts.FirstOrDefault(x => x.Name == member.Data);
                if (ctx == null)
                {
                    Error.Compile("Context mentioned to include '" + member.Data + "' does not exist.");
                    return;
                }

                //Skip?
                if (includedThisRun.Contains(member.Data))
                {
                    return;
                }

                //Include all members recursively with update list.
                includedThisRun.Add(member.Data);
                foreach (var mem in ctx.Members)
                {
                    AddContextMember(ctxName, mem, data, ref text);
                }
                return;
            }
        }