Ejemplo n.º 1
0
        private static List <Preprocessor.token> MatchArrayPostscript(TokenProvider tp)
        {
            List <Preprocessor.token> ret = new List <Preprocessor.token>();

            Preprocessor.token t = tp.Current;
            if (t.value == "[")
            {
                ret.Add(t);
                t = tp.MoveNext();
                if (t.type == Preprocessor.token.token_type.number)
                {
                    ret.Add(t);
                    t = tp.MoveNext();
                }

                if (t.value != "]")
                {
                    throw new Exception();
                }
                ret.Add(t);
                t = tp.MoveNext();
            }
            return(ret);
        }
Ejemplo n.º 2
0
        internal static ParsedEntry ParseFile(TokenProvider tp)
        {
            ParsedEntry ret = new ParsedEntry {
                Type = ParsedEntry.type.file, Tokens = tp.tokens
            };

            Preprocessor.token t = tp.Current;

            while (t.type != Preprocessor.token.token_type.beyond_eof)
            {
                if (t.type == Preprocessor.token.token_type.comment)
                {
                    t = tp.MoveNext();
                    continue;
                }

                List <Preprocessor.token> cur_tokens = new List <Preprocessor.token>();

                ParsedEntry entry = new ParsedEntry {
                    Tokens = cur_tokens
                };

                if (t.value == "typedef")
                {
                    cur_tokens.Add(t);
                    t = tp.MoveNext();
                    List <Preprocessor.token> typedef_to = MatchType(tp);
                    cur_tokens.AddRange(typedef_to);
                    t = tp.Current;
                    cur_tokens.Add(t);
                    string typedef_from = t.value;
                    t = tp.MoveNext();
                    if (t.value != ";")
                    {
                        throw new Exception();
                    }

                    typedefs.Add(typedef_from, typedef_to);
                    t          = tp.MoveNext();
                    entry.Type = ParsedEntry.type.typedef;
                }
                else
                {
                    // Parse type
                    List <Preprocessor.token> mtype = MatchType(tp);
                    if (mtype.Count == 0)
                    {
                        throw new Exception("Invalid type: " + tp.Current.value);
                    }
                    cur_tokens.AddRange(mtype);

                    // Read identifier
                    t = tp.Current;
                    if (t.type == Preprocessor.token.token_type.identifier)
                    {
                        cur_tokens.Add(t);
                        t = tp.MoveNext();
                    }

                    // See if we identify a function
                    if (t.value == "(")
                    {
                        // Function header
                        t = tp.MoveNext();

                        List <ParsedEntry> args = new List <ParsedEntry>();

                        while (t.value != ")")
                        {
                            List <Preprocessor.token> type = MatchType(tp);
                            cur_tokens.AddRange(type);
                            t = tp.Current;

                            if ((t.value != ")") && (t.value != ","))
                            {
                                type.Add(t);
                                cur_tokens.Add(t);
                                t = tp.MoveNext();
                            }

                            if (t.value == ")")
                            {
                                break;
                            }

                            if (t.value != ",")
                            {
                                throw new Exception();
                            }

                            args.Add(new ParsedEntry {
                                Type = ParsedEntry.type.variable_definition, Tokens = type
                            });

                            cur_tokens.Add(t);
                            t = tp.MoveNext();
                        }

                        entry.Children.AddRange(args);

                        cur_tokens.Add(t);
                        t = tp.MoveNext();

                        if (t.value == ";")
                        {
                            cur_tokens.Add(t);
                            t          = tp.MoveNext();
                            entry.Type = ParsedEntry.type.function_declaration;
                        }
                        else if (t.value == "{")
                        {
                            entry.Type = ParsedEntry.type.function_definition;
                            ParseStatementBlock(tp, entry);
                        }
                    }
                    else if (t.value == ";")
                    {
                        entry.Type = ParsedEntry.type.variable_definition;
                        cur_tokens.Add(t);
                        t = tp.MoveNext();
                    }
                    else if (t.value == "=")
                    {
                        entry.Type = ParsedEntry.type.variable_definition;
                        cur_tokens.Add(t);
                        t = tp.MoveNext();
                        ParseExpression(tp, entry);
                    }
                    else
                    {
                        throw new Exception();
                    }
                }

                ret.Children.Add(entry);
            }

            return(ret);
        }
Ejemplo n.º 3
0
        static List <Preprocessor.token> MatchType(TokenProvider tp)
        {
            List <Preprocessor.token> ret = new List <Preprocessor.token>();

            Preprocessor.token t = tp.Current;
            while (true)
            {
                if (t.type == Preprocessor.token.token_type.comment)
                {
                    t = tp.MoveNext();
                }
                else if ((t.value == "extern") || (t.value == "static") || (t.value == "const") || (t.value == "unsigned") ||
                         (t.value == "signed"))
                {
                    ret.Add(t);
                    t = tp.MoveNext();
                }
                else if ((t.value == "int") || (t.value == "long") || (t.value == "char") ||
                         (t.value == "short") || (t.value == "float") || (t.value == "double") ||
                         (t.value == "void"))
                {
                    ret.Add(t);
                    t = tp.MoveNext();

                    if (t.value == "*")
                    {
                        ret.Add(t);
                        t = tp.MoveNext();
                    }

                    if ((t.value != "long") && (t.value != "short") && (t.value != "int"))
                    {
                        return(ret);
                    }
                }
                else if (typedefs.ContainsKey(t.value))
                {
                    ret.AddRange(typedefs[t.value]);
                    t = tp.MoveNext();
                    return(ret);
                }
                else if ((t.value == "struct") || (t.value == "union"))
                {
                    ret.Add(t);
                    t = tp.MoveNext();

                    string struct_name = null;
                    if (t.value != "{")
                    {
                        struct_name = t.value;
                        ret.Add(t);
                        t = tp.MoveNext();
                    }


                    if (t.value == "{")
                    {
                        ret.Add(t);
                        t = tp.MoveNext();

                        // Read the struct definition
                        List <Preprocessor.token> struct_def = new List <Preprocessor.token>();

                        while (true)
                        {
                            List <Preprocessor.token> type = MatchType(tp);
                            if (type.Count == 0)
                            {
                                throw new Exception("Invalid type: " + tp.Current.value);
                            }

                            struct_def.AddRange(type);
                            ret.AddRange(type);

                            t = tp.Current;
                            if (t.type == Preprocessor.token.token_type.identifier)
                            {
                                struct_def.Add(t);
                                ret.Add(t);
                                t = tp.MoveNext();
                            }

                            List <Preprocessor.token> array = MatchArrayPostscript(tp);
                            struct_def.AddRange(array);
                            ret.AddRange(array);
                            t = tp.Current;


                            if (t.value != ";")
                            {
                                throw new Exception();
                            }
                            struct_def.Add(t);
                            ret.Add(t);

                            t = tp.MoveNext();
                            if (t.value == "}")
                            {
                                ret.Add(t);
                                break;
                            }
                        }

                        t = tp.MoveNext();

                        if (struct_name != null)
                        {
                            struct_defs.Add(struct_name, struct_def);
                        }
                    }
                    else if (struct_name == null)
                    {
                        throw new Exception("Invalid struct definition");
                    }
                    else if (!struct_defs.ContainsKey(struct_name))
                    {
                        throw new Exception("struct " + struct_name + " is not defined");
                    }

                    return(ret);
                }
                else
                {
                    throw new Exception("Invalid type: " + t.value);
                }
            }
        }