public PreprocessorContext(ParseContext pc, SymbolLookup symbols)
        {
            Symbols = symbols;
            parseContext = pc;
            inComment = false;

            InitAtomTable();
            InitScanner();

            ifdepth = 0;
            elseSeen = new bool[MAXIFNESTING];
            for (elsetracker = 0; elsetracker < MAXIFNESTING; elsetracker++)
                elseSeen[elsetracker] = false;
            elsetracker = 0;

            inputStack = new Stack<BasePreprocessorInput> ();

            buffer = new StringInputBuffer{ name = new char[StringInputBuffer.MAX_TOKEN_LENGTH], tokenText = new char[StringInputBuffer.MAX_TOKEN_LENGTH]};
        }
示例#2
0
        internal bool DoStuff(ParseContext parseContext, PreprocessorContext ppContext,
		               InputScanner input, bool versionWillBeError)
        {
            //bool versionWillBeError = true;
            var unNeededSpaceTokens = new HashSet<char>(new char[]{';','(',')','[',']'});
            var noSpaceBeforeTokens =  new HashSet<char>(new char[]{','});

            var outputStream = new StringBuilder();
            int lastLine = -1; // lastLine is the line number of the last token
            // processed. It is tracked in order for new-lines to be inserted when
            // a token appears on a new line.
            int lastToken = -1;
            parseContext.setScanner(input);
            ppContext.setInput(input, versionWillBeError);

            // Inserts newlines and incremnets lastLine until
            // lastLine >= line.
            Action<int> adjustLine = (line) =>
            {
                int tokenLine = line - 1;
                while(lastLine < tokenLine) {
                    if (lastLine >= 0) {
                        outputStream.AppendLine();
                    }
                    ++lastLine;
                }
            };

            parseContext.ExtensionCallback = (int line, string extension, string behavior) =>
            {
                adjustLine(line);
                outputStream.Append("#extension ").Append(extension).Append(" : ").Append(behavior);
            };

            parseContext.LineCallback = (int line, bool hasSource, int sourceNum) =>
            {
                // SourceNum is the number of the source-string that is being parsed.
                if (lastLine != -1) {
                    outputStream.AppendLine();
                }
                outputStream.Append("#line ").Append(line);
                if (hasSource) {
                    outputStream.Append(" ").Append(sourceNum);
                }
                outputStream.AppendLine();
                lastLine = System.Math.Max(line - 1, 1);
            };

            parseContext.VersionCallback = (int line, int version, string str) =>
            {
                adjustLine(line);
                outputStream.Append("#version ").Append(version);
                if (str != null) {
                    outputStream.Append(" ").Append(str);
                }
                outputStream.AppendLine();
                ++lastLine;
            };

            parseContext.PragmaCallback = (int line, List<string> ops) =>
            {
                adjustLine(line);
                outputStream.Append("#pragma ");
                foreach(var op in ops) {
                    outputStream.Append(op);
                }
            };

            parseContext.ErrorCallback = (int line, string errorMessage) =>
            {
                adjustLine(line);
                outputStream.Append("#error ").Append(errorMessage);
            };

            var token = new PreprocessorToken();
            string tok = ppContext.tokenize (ref token);
            while (tok != null) {
                int tokenLine = token.loc.line - 1;  // start at 0;
                bool newLine = false;
                while (lastLine < tokenLine) {
                    if (lastLine > -1) {
                        outputStream.AppendLine();
                        newLine = true;
                    }
                    ++lastLine;
                    if (lastLine == tokenLine) {
                        // Don't emit whitespace onto empty lines.
                        // Copy any whitespace characters at the start of a line
                        // from the input to the output.
                        for(int i = 0; i < token.loc.column - 1; ++i) {
                            outputStream.Append(" ");
                        }
                    }
                }

                // Output a space in between tokens, but not at the start of a line,
                // and also not around special tokens. This helps with readability
                // and consistency.
                if (!newLine &&
                    lastToken != -1 &&
                    (!unNeededSpaceTokens.Contains ((char)token.token)) &&
                    (!unNeededSpaceTokens.Contains((char)lastToken)) &&
                    (!noSpaceBeforeTokens.Contains ((char)token.token)))
                {
                    outputStream.Append(" ");
                }
                lastToken = token.token;
                outputStream.Append(tok);
                tok = ppContext.tokenize (ref token);
            }

            outputStream.AppendLine();
            Output = outputStream.ToString();

            return true;
        }