Exemplo n.º 1
0
        internal static List <token> Process(string input, Dictionary <string, List <token> > defines, Program.IncludeFileLocator file_locator)
        {
            /* The C standard defines eight phases of translation
             *
             * The first four are handled by the preprocessor:
             *  - Trigraph replacement
             *  - Line splicing (joining lines separated by the \ character)
             *  - Tokenization + replacing comments with whitespace
             *  - Marco expansion and directive handling
             */

            string post_trigraph = Replace(input, new string[][] {
                new string[] { "??=", "#" },
                new string[] { "??/", "\\" },
                new string[] { "??'", "^" },
                new string[] { "??(", "[" },
                new string[] { "??)", "]" },
                new string[] { "??!", "|" },
                new string[] { "??<", "{" },
                new string[] { "??>", "}" },
                new string[] { "??-", "~" },
            }, false);

            string       spliced_lines = SpliceLines(post_trigraph);
            List <token> tokens        = Tokenize(spliced_lines);

            int          i = 0;
            List <token> expanded_tokens = ConvertToTree(tokens, ref i);

            List <token> new_tokens = HandleDirectives(expanded_tokens, defines, file_locator);

            return(new_tokens);
        }
Exemplo n.º 2
0
        private static void HandleInclude(List <token> ret, List <token> tokens, int i, Dictionary <string, List <token> > defines, Program.IncludeFileLocator file_locator)
        {
            token file_name = tokens[i].parameters[0];

            if (file_name.value == "<")
            {
                file_name = new token {
                    type = token.token_type.identifier, value = tokens[i].value.Split(' ', '\t')[1].Trim()
                }
            }
            ;
            if ((file_name.type != token.token_type.identifier) && (file_name.type != token.token_type.string_literal))
            {
                throw new Exception();
            }

            bool search_cur_dir = false;

            if (file_name.value.StartsWith("\""))
            {
                search_cur_dir = true;
            }
            string fname = file_name.value.Trim('\"', '<', '>');

            string file_text = file_locator.ReadFile(fname, search_cur_dir);

            ret.AddRange(Process(file_text, defines, file_locator));
        }
Exemplo n.º 3
0
 private static void HandlePragma(List <token> ret, List <token> tokens, int i, Dictionary <string, List <token> > defines, Program.IncludeFileLocator file_locator)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 4
0
        private static void HandleDefine(List <token> ret, List <token> tokens, int i, Dictionary <string, List <token> > defines, Program.IncludeFileLocator file_locator)
        {
            token        macro_name = tokens[i].parameters[0];
            List <token> defined_as = new List <token>();

            for (int j = 1; j < tokens[i].parameters.Count; j++)
            {
                defined_as.Add(tokens[i].parameters[j]);
            }
            List <token> new_defined_as = HandleDirectives(defined_as, defines, file_locator);

            defines[macro_name.value] = new_defined_as;
        }
Exemplo n.º 5
0
 private static void HandleIfDef(List <token> ret, List <token> tokens, int i, Dictionary <string, List <token> > defines, Program.IncludeFileLocator file_locator)
 {
     if (tokens[i].parameters.Count != 1)
     {
         throw new Exception();
     }
     if (defines.ContainsKey(tokens[i].parameters[0].value))
     {
         ret.AddRange(HandleDirectives(tokens[i].if_tokens, defines, file_locator));
     }
     else
     {
         ret.AddRange(HandleDirectives(tokens[i].else_tokens, defines, file_locator));
     }
 }
Exemplo n.º 6
0
        private static List <token> HandleDirectives(List <token> tokens, Dictionary <string, List <token> > defines, Program.IncludeFileLocator file_locator)
        {
            List <token> ret = new List <token>();

            if (tokens == null)
            {
                return(ret);
            }

            for (int i = 0; i < tokens.Count; i++)
            {
                token tok = tokens[i];

                if (tok.type == token.token_type.preprocessor_directive)
                {
                    string directive = tok.directive;

                    if (directive == "#include")
                    {
                        HandleInclude(ret, tokens, i, defines, file_locator);
                    }
                    else if (directive == "#if")
                    {
                        HandleIf(ret, tokens, i, defines, file_locator);
                    }
                    else if (directive == "#ifdef")
                    {
                        HandleIfDef(ret, tokens, i, defines, file_locator);
                    }
                    else if (directive == "#define")
                    {
                        HandleDefine(ret, tokens, i, defines, file_locator);
                    }
                    else if (directive == "#error")
                    {
                        HandleError(ret, tokens, i, defines, file_locator);
                    }
                    else if (directive == "#warning")
                    {
                        HandleWarning(ret, tokens, i, defines, file_locator);
                    }
                    else if (directive == "#pragma")
                    {
                        HandlePragma(ret, tokens, i, defines, file_locator);
                    }
                    else if (directive == "#ifndef")
                    {
                        HandleIfndef(ret, tokens, i, defines, file_locator);
                    }
                    else
                    {
                        throw new Exception("Unsupported preprocessor directive: " + tok.value);
                    }
                }
                else
                {
                    if ((tok.type == token.token_type.identifier) && defines.ContainsKey(tok.value))
                    {
                        ret.AddRange(defines[tok.value]);
                    }
                    else
                    {
                        ret.Add(tok);
                    }
                }
            }

            return(ret);
        }