Exemple #1
0
        public TypedInteger ResolveAddressExpression(SimpleToken[] addressExpression)
        {
            var reader = new SimpleTokenReader(addressExpression.ToList());

            reader.ReadNext(true);
            return(ResolveAddressExpressionRecursively(reader));
        }
Exemple #2
0
        TypedInteger ResolveAddressExpressionRecursively(SimpleTokenReader reader)
        {
            TypedInteger value = null;

            for (; ;)
            {
                if (value == null)
                {
                    value = ReadSingleAtom(reader);
                }

                if (reader.EOF || reader.Current.Value == ")")
                {
                    return(value);
                }

                if (reader.Current.Type != CppTokenizer.TokenType.Operator)
                {
                    throw new Exception("Expected an operator");
                }

                var op = reader.Current.Value;
                reader.ReadNext(true);
                var next = ReadSingleAtom(reader);

                if (value == null || next == null)
                {
                    return(null);
                }

                switch (op)
                {
                case "+":
                case "-":
                    if (next.IsAPointer)
                    {
                        throw new Exception("Cannot add pointers");
                    }

                    if (value.IsAPointer)
                    {
                        //We need to multiply this by the pointer size
                        throw new NotImplementedException();
                    }

                    if (op == "+")
                    {
                        value = new TypedInteger {
                            Value = value.Value + next.Value, Type = value.Type
                        }
                    }
                    ;
                    else
                    {
                        value = new TypedInteger {
                            Value = value.Value - next.Value, Type = value.Type
                        }
                    };

                    break;

                case "<<":
                    if (next.IsAPointer || value.IsAPointer)
                    {
                        throw new Exception("Cannot shift pointers");
                    }

                    value = new TypedInteger {
                        Value = value.Value << (int)next.Value, Type = value.Type
                    };
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }
Exemple #3
0
        //On entry, reader should point to the first available token. On exit, it will point to the first token AFTER the read expression.
        TypedInteger ReadSingleAtom(SimpleTokenReader reader)
        {
            if (reader.Current.Type == CppTokenizer.TokenType.Bracket && reader.Current.Value == "(")
            {
                var token = reader.ReadNext(true);
                if (token.Type == CppTokenizer.TokenType.Identifier && !char.IsNumber(token.Value[0]))
                {
                    //This is a cast operator (e.g. "(void *)0x1234").
                    List <SimpleToken> typeTokens = new List <SimpleToken>();
                    typeTokens.Add(token);
                    int level = 0;
                    for (; ;)
                    {
                        token = reader.ReadNext(true);
                        if (token.Type == CppTokenizer.TokenType.Bracket)
                        {
                            if (token.Value == "(")
                            {
                                level++;
                            }
                            else if (token.Value == ")")
                            {
                                level--;
                            }
                        }

                        if (level < 0)  //Found a closing bracket for the cast
                        {
                            reader.ReadNext(true);
                            break;
                        }

                        typeTokens.Add(token);
                    }

                    TypedInteger value = ReadSingleAtom(reader);
                    if (value != null)
                    {
                        value.Type = typeTokens.ToArray();
                    }
                    return(value);
                }
                else
                {
                    //Other bracketed expression
                    var value = ResolveAddressExpressionRecursively(reader);
                    if (reader.Current.Value != ")")
                    {
                        throw new Exception("Expected ')'");
                    }
                    reader.ReadNext(true);
                    return(value);
                }
            }
            else if (reader.Current.Type == CppTokenizer.TokenType.Identifier)
            {
                var   token = reader.Current;
                ulong?value = HeaderFileParser.TryParseMaybeHex(token.Value);

                reader.ReadNext(true);

                if (!value.HasValue)
                {
                    if (_ThrowOnFailure)
                    {
                        throw new UnexpectedNonNumberException(token);
                    }
                    else
                    {
                        return(null);
                    }
                }

                return(new TypedInteger {
                    Value = value.Value
                });
            }
            else
            {
                if (_ThrowOnFailure)
                {
                    throw new Exception("Invalid atom: " + reader.Current.Value);
                }
                else
                {
                    return(null);
                }
            }
        }
Exemple #4
0
        private void ExtractStructureDefinitions(List <SimpleToken> tokens, Dictionary <string, ParsedStructure> structures)
        {
            SimpleTokenReader reader = new SimpleTokenReader(tokens);

            while (!reader.EOF)
            {
                var token = reader.ReadNext(true);
                if (token.Type != CppTokenizer.TokenType.Identifier || token.Value != "typedef")
                {
                    continue;
                }

                token = reader.ReadNext(true);
                if (token.Type != CppTokenizer.TokenType.Identifier || token.Value != "struct")
                {
                    continue;
                }

                token = reader.ReadNext(true);
                if (token.Type == CppTokenizer.TokenType.Identifier)
                {
                    token = reader.ReadNext(true);  //Skip through the struct name definition, as we will use the typedef name
                }
                if (token.Type != CppTokenizer.TokenType.Bracket || token.Value != "{")
                {
                    ReportUnexpectedToken(token);
                    continue;
                }

                List <ParsedStructure.Entry> entries = new List <ParsedStructure.Entry>();
                List <SimpleToken>           tokensInThisStatement = new List <SimpleToken>();

                while (!reader.EOF)
                {
                    token = reader.ReadNext(false);
                    if (token.Type == CppTokenizer.TokenType.Comment)
                    {
                        if (entries.Count > 0)
                        {
                            entries[entries.Count - 1].TrailingComment = token.Value;
                        }
                    }
                    if (token.Type == CppTokenizer.TokenType.Bracket && token.Value == "{")
                    {
                        //Nested structs are not supported
                        ReportUnexpectedToken(token);
                        break;
                    }
                    else if (token.Type == CppTokenizer.TokenType.Bracket && token.Value == "}")
                    {
                        token = reader.ReadNext(true);
                        if (token.Type != CppTokenizer.TokenType.Identifier)
                        {
                            ReportUnexpectedToken(token);
                        }
                        else
                        {
                            structures[token.Value] = new ParsedStructure(token.Value, entries.ToArray());
                        }

                        break;
                    }
                    else if (token.Type == CppTokenizer.TokenType.Operator && token.Value == ";")
                    {
                        entries.Add(ParseSingleStructureMember(tokensInThisStatement));
                        tokensInThisStatement.Clear();
                    }
                    else
                    {
                        tokensInThisStatement.Add(token);
                    }
                }
            }
        }