コード例 #1
0
 public ParserTemplateContext(Options options,
                              string?ns,
                              Language language,
                              Productions.Grammar grammar,
                              LR1.LR1Parser lr1Parser,
                              ScannerBuilder.ScannerWriter scanner)
 {
     this.options   = options;
     this.ns        = ns ?? language.Namespace.Value;
     this.language  = language;
     this.grammar   = grammar;
     this.lr1Parser = lr1Parser;
     this.scanner   = scanner;
 }
コード例 #2
0
        public bool Compile()
        {
            var fileName = Path.GetFileName(inPath);
            var fileDir  = Path.GetDirectoryName(fileName);

            parser = Parser.FromString(args.InputContents);
            parser.SetOptions(options);
            args.LogMessage(Importance.Normal, "Parsing {0}", fileName);
            var isOk = parser.Parse();

            if (!isOk)
            {
                return(isOk);
            }

            var lang = parser.Language;

            if (lang == null)
            {
                return(false);
            }
            prods = lang.Productions;

            var nfa = parser.Graph;

            if (!prods.SetStates(args, parser.Graph.Machine.AcceptingStates))
            {
                return(false);
            }

            if (options.TryGetValue("nfa", out var nfaPath))
            {
                if (string.IsNullOrEmpty(nfaPath))
                {
                    nfaPath = Path.ChangeExtension(inPath, ".nfa.txt");
                }
                File.WriteAllText(nfaPath, nfa.ToString());
            }

            args.LogMessage(Importance.Normal, "Building dfa");
            dfa = nfa.ToDfa();

            scannerWriter = (!options.TryGetValue("scanner", out var scannerValue) ||
                             scannerValue.Equals("state", StringComparison.InvariantCultureIgnoreCase)) ?
                            new DfaStateWriter(dfa) as IGeneratable :
                            new DfaSwitchWriter(dfa);


            args.LogMessage(Importance.Normal, "Building LR1");
            var grammar     = new LR1.Grammar(lang.Productions);
            var grammarPath = Path.ChangeExtension(inPath, ".grammar.txt");
            var grammarText = grammar.ToString();

            File.WriteAllText(grammarPath, grammarText);

            lr1Parser = new LR1.LR1Parser(args, grammar);

            var statesPath = Path.ChangeExtension(inPath, ".states.txt");

            File.WriteAllText(statesPath, lr1Parser.States.ToString());


            using (var csharp = new Generator(args.Output))
            {
                if (!string.IsNullOrEmpty(args.DefaultNamespace))
                {
                    lang.Namespace = new ParseTree.Identifier(args.DefaultNamespace);
                }

                var frameSpecified = false;
                if (options.TryGetValue("frame", out var frameFile) && !string.IsNullOrEmpty(frameFile))
                {
                    frameSpecified = File.Exists(frameFile);
                    if (!frameSpecified)
                    {
                        frameFile      = Path.Combine(fileDir, frameFile);
                        frameSpecified = File.Exists(frameFile);
                        if (!frameSpecified)
                        {
                            args.LogWarning("Unable to find frame file {0}", frameFile);
                        }
                    }
                }
                if (frameSpecified)
                {
                    args.LogMessage(Importance.Normal, "Using frame file {0}", frameFile);
                    //args.LogMessage(Importance.Normal, "Writing output {0}", OutPath);
                    TemplateProcessor.FromFile(csharp, this, frameFile);
                }
                else
                {
                    args.LogMessage(Importance.Normal, "Using internal frame file");
                    //args.LogMessage(Importance.Normal, "Writing output {0}", OutPath);
                    TemplateProcessor.FromAssembly(csharp, this, "Opal.FrameFiles.Parser.txt");
                }
            }

            return(isOk);
        }