private bool TryGetSimpleWriteFromVar(AstToken token, out DeclRefExprProperties properties) { properties = null; switch (token.Type) { case AstType.DeclRefExpr when token.children.Count == 0: properties = new DeclRefExprProperties(token); return(true); // case AstType.CXXOperatorCallExpr when IsPacketShiftExpression(token): case AstType.ImplicitCastExpr: foreach (var tokenChild in token.children) { if (TryGetSimpleWriteFromVar(tokenChild, out properties)) { return(true); } } break; default: break; } return(false); }
//protected static string GetValue(AstToken token) //{ // switch (token.name) // { // case "InitListExpr": // System.Text.StringBuilder builder = new System.Text.StringBuilder(); // builder.Append("["); // for (int i = 0; i < token.children.Count; i++) // { // if (i != 0) builder.Append(","); // builder.Append(GetValue(token.children[i])); // } // builder.Append("]"); // return builder.ToString(); // case "ImplicitCastExpr": // if (token.children.Count > 1) throw new InvalidCastException(); // return GetValue(token.children[0]); // case "CXXBoolLiteralExpr": // return token.properties[1]; // property 0 is 'bool' // case "IntegerLiteral": // return token.properties[1]; // property 0 is 'int'; if this one have context - this may be define // case "GNUNullExpr": // return "null"; // case "StringLiteral": // return token.properties[2]; // property 0 is 'char[...]', property 1 is 'lvalue' // case "CStyleCastExpr": // if (token.children.Count > 1) throw new InvalidCastException(); // return GetValue(token.children[0]); // here probably need append cast prefix // case "DeclRefExpr": // return token.properties[3]; // here need check for pointer to declaration // case "UnaryOperator": // var operation = token.properties[1]; // if (operation == "prefix") return token.properties[token.properties.Length - 1] + GetValue(token.children[0]); // else if (operation == "postfix") return GetValue(token.children[0]) + token.properties[token.properties.Length - 1]; // else throw new Exception(operation); // case "BinaryOperator": // return GetValue(token.children[0]) + token.properties[token.properties.Length - 1] + GetValue(token.children[1]); // case "ParenExpr": // return "(" + GetValue(token.children[0]) + ")"; // default: throw new Exception(token.name); // } //} protected static VariableDeclaration GetVariableDeclaration(AstToken token) { var variable = new VariableDeclaration() { name = token.properties[0], type = token.properties[1], }; if (token.attributes.Contains("cinit")) { variable.value = GetFunctionBody(token.children[0]); } if (token.attributes.Contains("static")) { variable.isStatic = true; } if (token.attributes.Contains("extern")) { variable.isExtern = true; } for (int i = 2; i < token.properties.Length; i++) { switch (token.properties[i]) { default: throw new Exception(token.properties[i]); } } return(variable); }
private static DeclRefExprProperties GetChildAccesor(AstToken token) { if (token.Type == AstType.DeclRefExpr && token.children.Count == 0) { return(new DeclRefExprProperties(token)); } if (token.Type == AstType.MemberExpr && token.children.Count > 0 && token.properties[0] == "<bound member function type>") { var func = token.properties[1]; //Debugger.Break(); } if (token.Type == AstType.CXXMemberCallExpr) { Debugger.Break(); } foreach (var tokenChild in token.children) { var accessor = GetChildAccesor(tokenChild); if (accessor != null) { return(accessor); } } return(null); }
private bool TryGetMethodCallWrite(AstToken token, out string name) { //ImplicitCastExpr name = string.Empty; DeclRefExprProperties properties = null; switch (token.Type) { case AstType.MemberExpr when token.properties[0] == "<bound member function type>": name = token.properties[1]; name = name.TrimStart("->").TrimStart("Get"); return(true); case AstType.CXXMemberCallExpr: foreach (var tokenChild in token.children) { if (TryGetMethodCallWrite(tokenChild, out name)) { return(true); } } break; default: break; } return(false); return(false); }
private bool TryGetPacketWriteOverloadType(AstToken token, out string typeName) { switch (token.Type) { case AstType.ImplicitCastExpr: foreach (var tokenChild in token.children) { if (TryGetPacketWriteOverloadType(tokenChild, out typeName)) { return(true); } } break; case AstType.DeclRefExpr: var match = Regex.Match(token.properties[0], "CPacket.*?\\((.*?)\\)"); if (match.Success) { typeName = match.Groups[1].Value; return(true); } break; default: break; } typeName = string.Empty; return(false); }
private static IEnumerable <DeclRefExprProperties> GetVariableThatGetsSaid(AstToken methodDecl) { var memberExpressions = methodDecl.VisitEnumerable ( x => x.Type == AstType.MemberExpr && x.parent.Type == AstType.CXXMemberCallExpr && x.properties.Contains("->Say") ); foreach (var memberExpression in memberExpressions) { var otherchildren = memberExpression.parent .VisitEnumerable(x => x != memberExpression) .Where(x => x.Type == AstType.DeclRefExpr) .Select(x => new DeclRefExprProperties(x)) .ToList() ; //Just take the last one if (otherchildren.Count == 1) { yield return(otherchildren.FirstOrDefault()); } else { //Multiple (path: pSession->Say( &vMSG )) yield return(otherchildren.FirstOrDefault(x => x.Token.properties[0] == "CPacket")); } } }
protected static void ProcessStructDeclaration(AstToken token) { var targetClass = GetTranslatedTargetClass(token.context.sourceFile); var targetFileName = GetTranslatedTargetFile(token.context.sourceFile); var translationFile = GetTranslation(targetClass); var structure = GetStructDeclaration(token); translationFile.structures.Add(token.offset, structure); }
protected static FunctionProtoDeclaration GetFunctionProtoDeclaration(AstToken token) { var function = new FunctionProtoDeclaration() { returnType = GetTypeDeclaration(token.children[0]) }; for (int i = 1; i < token.children.Count; i++) { function.parameters.Add(GetTypeDeclaration(token.children[i])); } return(function); }
protected static void ProcessTypedef(AstToken token) { var targetClass = GetTranslatedTargetClass(token.context.sourceFile); var targetFileName = GetTranslatedTargetFile(token.context.sourceFile); var translationFile = GetTranslation(targetClass); var aliasType = GetTypeDeclaration(token.children[0]); translationFile.typedef.Add(token.offset, new TypedefDeclaration() { name = token.properties[0], alias = aliasType }); }
protected static FunctionDeclaration GetFunctionDeclaration(AstToken token) { var function = new FunctionDeclaration() { name = token.properties[0], }; foreach (var childToken in token.children) { switch (childToken.name) { case "ParmVarDecl": FunctionDeclaration.Parameter parameter = null; if (childToken.properties.Length == 1) { parameter = new FunctionDeclaration.Parameter() { name = null, type = childToken.properties[0], }; } else if (childToken.properties.Length == 2) { parameter = new FunctionDeclaration.Parameter() { name = childToken.properties[0], type = childToken.properties[1], }; } if (childToken.attributes.Contains("cinit")) { parameter.value = GetFunctionBody(childToken.children[0]); } function.parameters.Add(parameter); break; case "CompoundStmt": function.body = GetFunctionBody(childToken); break; case "FullComment": break; // ignore default: throw new Exception(childToken.name); } } return(function); }
protected static void ProcessVariableDeclaration(AstToken token) { var targetClass = GetTranslatedTargetClass(token.context.sourceFile); var targetFileName = GetTranslatedTargetFile(token.context.sourceFile); var translationFile = GetTranslation(targetClass); var variable = GetVariableDeclaration(token); translationFile.variables.Add(token.offset, variable); //if (variable.value != null) //{ // Console.WriteLine(variable.name + " = " + variable.value); //} }
protected static void ProcessMainLevelToken(AstToken token) { // process only non standart file source if (!token.context.sourceFile.StartsWith("<", StringComparison.InvariantCulture) && !token.context.sourceFile.StartsWith("/usr", StringComparison.InvariantCulture)) { switch (token.name) { case "TypedefDecl": ProcessTypedef(token); break; case "UsingDirectiveDecl": // Console.WriteLine(" using {0}", string.Join(" ", token.properties)); break; case "VarDecl": ProcessVariableDeclaration(token); break; case "FunctionDecl": ProcessFunctionDeclaration(token); break; case "EnumDecl": ProcessEnum(token); break; case "CXXRecordDecl": // declaration of struct/class without body ProcessStructDeclaration(token); break; case "EmptyDecl": break; case "LinkageSpecDecl": foreach (var childToken in token.children) { ProcessMainLevelToken(childToken); } break; default: throw new NotImplementedException(token.name); } } }
private static void ProcessMethod(HashSet <AstType> forbidden, AstToken methodDecl, DeclRefExprProperties saidMsg) { // Should be able to handle all later... var usages = GetUsages(saidMsg, methodDecl).ToList(); foreach (var usage in usages) { var parentsInMethod = usage.parent.TraverseParents() .TakeWhile(x => x != methodDecl) .ToList(); var allOperatorExpressions = parentsInMethod .Where(x => x.Type == AstType.CXXOperatorCallExpr) .Where(x => x.properties.Length == 3 && (x.properties[2] == "<<" || x.properties[2] == "'<<'")) .ToList(); var goodParents = allOperatorExpressions .Where(x => x.children.Count == 3) .ToList(); foreach (var parent in goodParents) { var decl = parent.children[2].VisitEnumerable(x => x.Type == AstType.DeclRefExpr).FirstOrDefault(); if (decl == null) { continue; } var properties = new DeclRefExprProperties(decl); Console.WriteLine($"\t[{properties.InstanceId}] {properties.Name} ({properties.Type})"); var illegalOperation = EnumerableExtensions.TakeWhile(decl.TraverseParents(), x => x != methodDecl).FirstOrDefault(x => forbidden.Contains(x.Type)); if (illegalOperation != null) { Console.WriteLine($"\tIllegal operation - {illegalOperation.Type}"); DebugNodes(decl.TraverseParents().TakeWhile(x => x != methodDecl)); Console.WriteLine(); } } } }
protected static void ProcessFunctionDeclaration(AstToken token) { var targetClass = GetTranslatedTargetClass(token.context.sourceFile); var targetFileName = GetTranslatedTargetFile(token.context.sourceFile); var translationFile = GetTranslation(targetClass); var function = GetFunctionDeclaration(token); translationFile.functions.Add(token.offset, function); //Console.Write(function.name + "("); //foreach (var param in function.parameters) //{ // Console.Write(param.type+" "); // if (param.name != null) // Console.Write(param.name + " "); // if (param.value != null) // Console.Write("= "+param.value); // Console.Write(", "); //} //Console.WriteLine(")"); }
protected static void ProcessEnum(AstToken token) { var targetClass = GetTranslatedTargetClass(token.context.sourceFile); var targetFileName = GetTranslatedTargetFile(token.context.sourceFile); var translationFile = GetTranslation(targetClass); EnumDeclaration enumDeclaration = new EnumDeclaration() { name = token.properties.Length > 0 ? token.properties[0] : "[UnnamedEnum]" }; foreach (var childToken in token.children) { switch (childToken.name) { case "EnumConstantDecl": var enumConstant = new EnumDeclaration.Property() { name = childToken.properties[0] }; if (childToken.children.Count > 0) { foreach (var subChildToken in childToken.children) { enumConstant.value = GetFunctionBody(subChildToken); } } enumDeclaration.properties.Add(enumConstant); break; case "FullComment": break; default: throw new Exception(childToken.name); } } translationFile.enums.Add(token.offset, enumDeclaration); }
protected static StructureDeclaration GetStructDeclaration(AstToken token) { StructureDeclaration structure = new StructureDeclaration(); if (token.properties[0] == "union") { structure.isUnion = true; } else if (token.properties[0] == "class") { structure.isClass = true; } else if (token.properties[0] != "struct") { throw new ArgumentException(); } if (token.properties.Length > 1) { structure.name = token.properties[1]; } foreach (var childToken in token.children) { switch (childToken.name) { case "DefinitionData": // almost no idea how to parse it // TODO break; case "CXXRecordDecl": structure.subStructures.Add(GetStructDeclaration(childToken)); break; case "FieldDecl": structure.properties.Add(new StructureDeclaration.Property() { name = childToken.properties[0], type = childToken.properties[1] }); break; case "public": // TODO break; case "FullComment": // ignore this. or TODO if you wish break; case "AccessSpecDecl": // TODO local modificator based on properties[0] break; case "CXXConstructorDecl": // TODO break; case "CXXDestructorDecl": // TODO break; case "CXXMethodDecl": // TODO structure.others.Add(childToken.properties[0] + " " + childToken.properties[1]); break; default: throw new Exception(childToken.name); } } return(structure); }
private static IEnumerable <AstToken> GetUsages(DeclRefExprProperties saidMsg, AstToken methodDecl) { return(methodDecl.VisitEnumerable ( x => x.Type == AstType.DeclRefExpr && new DeclRefExprProperties(x).Equals(saidMsg) )); }
private bool IsPacketShiftExpression(AstToken token) { return(token.Type == AstType.CXXOperatorCallExpr && token.properties.Length <= 3 && (token.properties[2] == "<<" || token.properties[2] == "'<<'")); }
protected static TypeDeclaration GetTypeDeclaration(AstToken token) { switch (token.name) { case "BuiltinType": return(new TypeDeclaration() { name = token.properties[0], isBuildIn = true }); case "PointerType": var pointerDeclaration = GetTypeDeclaration(token.children[0]); pointerDeclaration.isPointer = true; return(pointerDeclaration); case "RecordType": return(new TypeDeclaration() { name = token.properties[0] }); case "ElaboratedType": // struct return(GetTypeDeclaration(token.children[0])); case "TypedefType": return(new TypeDeclaration() { name = token.properties[0] }); case "ParenType": switch (token.children[0].name) { case "FunctionProtoType": var functionDeclaration = GetFunctionProtoDeclaration(token.children[0]); functionDeclaration.name = token.properties[0]; functionDeclaration.isBuildIn = false; return(functionDeclaration); default: throw new NotImplementedException(token.children[0].name); } case "QualType": // type with modificator return(GetTypeDeclaration(token.children[0])); case "EnumType": // type with modificator return(new TypeDeclaration() { name = token.properties[0] }); case "...": // params return(new TypeDeclaration() { name = token.name }); case "TemplateSpecializationType": return(null); // TODO default: throw new NotImplementedException(token.name); } }
protected static string GetFunctionBody(AstToken token) { string reference; System.Text.StringBuilder stringBuilder; switch (token.name) { case "CompoundStmt": stringBuilder = new System.Text.StringBuilder(); stringBuilder.AppendLine("{"); foreach (var childToken in token.children) { stringBuilder.AppendLine(GetFunctionBody(childToken)); } stringBuilder.AppendLine("}"); return(stringBuilder.ToString()); case "ReturnStmt": if (token.children.Count > 1) { throw new ArgumentException(); } if (token.children.Count == 0) { return("return;"); } return("return " + GetFunctionBody(token.children[0]) + ";"); case "ConditionalOperator": if (token.children.Count != 3) { throw new ArgumentException(); } return(GetFunctionBody(token.children[0]) + "?" + GetFunctionBody(token.children[1]) + ":" + GetFunctionBody(token.children[2])); case "ParenExpr": if (token.children.Count != 1) { throw new ArgumentException(); } return("(" + GetFunctionBody(token.children[0]) + ")"); case "BinaryOperator": return(GetFunctionBody(token.children[0]) + token.properties[token.properties.Length - 1] + GetFunctionBody(token.children[1])); case "UnaryOperator": if (token.children.Count != 1) { throw new ArgumentException(); } var operation = token.properties[1]; if (operation == "lvalue") { operation = token.properties[2]; } if (operation == "prefix") { return(token.properties[token.properties.Length - 1] + GetFunctionBody(token.children[0])); } else if (operation == "postfix") { return(GetFunctionBody(token.children[0]) + token.properties[token.properties.Length - 1]); } else { throw new ArgumentException(); } case "ImplicitCastExpr": if (token.children.Count != 1) { throw new ArgumentException(); } return(GetFunctionBody(token.children[0])); case "DeclRefExpr": // variable reference = token.properties[1]; if (reference == "lvalue") { return(token.properties[4]); // remove quotes } return(token.properties[3]); // remove quotes case "InitListExpr": stringBuilder = new System.Text.StringBuilder(); stringBuilder.Append("["); for (int i = 0; i < token.children.Count; i++) { if (i != 0) { stringBuilder.Append(","); } stringBuilder.Append(GetFunctionBody(token.children[i])); } stringBuilder.Append("]"); return(stringBuilder.ToString()); case "IntegerLiteral": return(token.properties[1]); // property 0 is 'int'; if this one have context - this may be define case "CharacterLiteral": return(token.properties[1]); // property 0 is 'char' case "FloatingLiteral": return(token.properties[1]); // property 0 is 'float/double' case "StringLiteral": reference = token.properties[1]; // property 0 is 'char[...]' if (reference == "lvalue") { return(token.properties[2]); } return(token.properties[1]); case "CXXBoolLiteralExpr": return(token.properties[1]); // property 0 is 'bool' case "CStyleCastExpr": if (token.children.Count != 1) { throw new ArgumentException(); } return(GetFunctionBody(token.children[0])); // maybe need cast with parameter[0] case "MemberExpr": if (token.children.Count != 1) { throw new ArgumentException(); } reference = token.properties[1]; if (reference == "lvalue") { return(GetFunctionBody(token.children[0]) + token.properties[2]); } return(GetFunctionBody(token.children[0]) + token.properties[1]); case "CallExpr": if (token.children.Count == 0) { throw new ArgumentException(); } stringBuilder = new System.Text.StringBuilder(); stringBuilder.Append(GetFunctionBody(token.children[0])); stringBuilder.Append("("); for (int i = 1; i < token.children.Count; i++) { if (token.children[i].name == "CXXDefaultArgExpr") { break; } if (i > 1) { stringBuilder.Append(","); } stringBuilder.Append(GetFunctionBody(token.children[i])); } stringBuilder.Append(")"); return(stringBuilder.ToString()); case "ArraySubscriptExpr": if (token.children.Count != 2) { throw new ArgumentException(); } return(GetFunctionBody(token.children[0]) + "[" + GetFunctionBody(token.children[1]) + "]"); case "DeclStmt": stringBuilder = new System.Text.StringBuilder(); foreach (var childToken in token.children) { stringBuilder.AppendLine(GetFunctionBody(childToken)); } return(stringBuilder.ToString()); case "VarDecl": if (token.properties.Length != 2) { throw new ArgumentException(); } stringBuilder = new System.Text.StringBuilder(); stringBuilder.Append(token.properties[1]); stringBuilder.Append(" "); stringBuilder.Append(token.properties[0]); if (token.attributes.Contains("cinit")) { if (token.children.Count != 1) { token.children = token.children.Where((tok, index) => tok.name != "FullComment").ToList(); if (token.children.Count != 1) { throw new ArgumentException(); } } stringBuilder.Append(" = "); stringBuilder.Append(GetFunctionBody(token.children[0])); } return(stringBuilder.ToString() + ";"); case "WhileStmt": if (token.children.Count != 3) { throw new ArgumentException(); } return("while(" + GetFunctionBody(token.children[1]) + ")\n" + GetFunctionBody(token.children[2])); case "DoStmt": if (token.children.Count != 2) { throw new ArgumentException(); } return("do" + GetFunctionBody(token.children[0]) + "\nwhile(" + GetFunctionBody(token.children[1]) + ");"); case "IfStmt": if (token.children.Count != 5) { throw new ArgumentException(); } return("if(" + GetFunctionBody(token.children[2]) + ")\n" + GetFunctionBody(token.children[3])); case "ForStmt": if (token.children.Count != 5) { throw new ArgumentException(); } return("for(" + GetFunctionBody(token.children[0]) + ";" + GetFunctionBody(token.children[2]) + ";" + GetFunctionBody(token.children[3]) + ")\n" + GetFunctionBody(token.children[4])); case "GNUNullExpr": return("null"); case "NullStmt": return(";"); case "CompoundAssignOperator": if (token.children.Count != 2) { throw new ArgumentException(); } reference = token.properties[1]; if (reference == "lvalue") { return(GetFunctionBody(token.children[0]) + token.properties[2] + GetFunctionBody(token.children[1])); } return(GetFunctionBody(token.children[0]) + token.properties[1] + GetFunctionBody(token.children[1])); case "UnaryExprOrTypeTraitExpr": if (token.properties.Length == 3) { return(token.properties[1] + "(" + token.properties[2] + ")"); } if (token.children.Count != 1) { throw new ArgumentException(); } return(token.properties[1] + GetFunctionBody(token.children[0])); case "BreakStmt": return("break;"); case "ContinueStmt": return("continue;"); case "GotoStmt": return("goto " + token.properties[0] + ";"); case "LabelStmt": stringBuilder = new System.Text.StringBuilder(); stringBuilder.Append(token.properties[0]); stringBuilder.AppendLine(":"); foreach (var childToken in token.children) { stringBuilder.AppendLine(GetFunctionBody(childToken)); } return(stringBuilder.ToString()); case "ExprWithCleanups": // i not sure about this one if (token.children.Count != 1) { throw new ArgumentException(); } return(GetFunctionBody(token.children[0])); case "CXXConstructExpr": // i not sure about this one if (token.children.Count != 1) { throw new ArgumentException(); } return(GetFunctionBody(token.children[0])); case "MaterializeTemporaryExpr": // i not sure about this one if (token.children.Count != 1) { throw new ArgumentException(); } return(GetFunctionBody(token.children[0])); case "CXXMemberCallExpr": // i not sure about this one stringBuilder = new System.Text.StringBuilder(); stringBuilder.Append(GetFunctionBody(token.children[0])); stringBuilder.Append("("); for (int i = 1; i < token.children.Count; i++) { //if (token.children[i].name == "CXXDefaultArgExpr") break; if (i > 1) { stringBuilder.Append(","); } stringBuilder.Append(GetFunctionBody(token.children[i])); } stringBuilder.Append(")"); return(stringBuilder.ToString()); case "CXXOperatorCallExpr": // i not sure about this one if (token.children.Count == 3) { return(GetFunctionBody(token.children[1]) + GetFunctionBody(token.children[0]) + GetFunctionBody(token.children[2])); } else if (token.children.Count == 2) { return(GetFunctionBody(token.children[1]) + GetFunctionBody(token.children[0])); } else { throw new ArgumentException(); } case "ImplicitValueInitExpr": // don't know what to do if (token.children.Count != 0) { throw new ArgumentException(); } return(""); case "SwitchStmt": if (token.children.Count != 4) { throw new ArgumentException(); } stringBuilder = new System.Text.StringBuilder(); stringBuilder.Append("switch("); stringBuilder.Append(GetFunctionBody(token.children[2])); stringBuilder.Append(")"); stringBuilder.Append(GetFunctionBody(token.children[3])); return(stringBuilder.ToString()); case "CaseStmt": if (token.children.Count != 3) { throw new ArgumentException(); } stringBuilder = new System.Text.StringBuilder(); stringBuilder.Append("case:"); stringBuilder.AppendLine(GetFunctionBody(token.children[0])); stringBuilder.Append(GetFunctionBody(token.children[2])); return(stringBuilder.ToString()); case "DefaultStmt": stringBuilder = new System.Text.StringBuilder(); for (int i = 0; i < token.children.Count; i++) { stringBuilder.Append(GetFunctionBody(token.children[i])); } return(stringBuilder.ToString()); case "array": return(""); // no idea what to do... case "CXXStaticCastExpr": if (token.children.Count != 1) { throw new ArgumentException(); } return(GetFunctionBody(token.children[0])); case "CXXFunctionalCastExpr": // i not sure it works right return("(" + token.properties[0] + ")"); case "PredefinedExpr": // i not sure it works right operation = token.properties[1]; if (operation == "lvalue") { operation = token.properties[2]; } return(operation); case "<<<NULL>>>": return(""); case "GCCAsmStmt": stringBuilder = new System.Text.StringBuilder(); for (int i = 0; i < token.children.Count; i++) { stringBuilder.Append(GetFunctionBody(token.children[i])); } return(stringBuilder.ToString()); case "VAArgExpr": // i not sure it right return("...args"); default: throw new Exception(token.name); //default: return "Unknown"; } }
public void VisitTest(AstToken token) { if (token.Type == AstType.ForStmt) { Console.WriteLine("For statement"); } foreach (var child in token.children) { VisitTest(child); } if (IsPacketShiftExpression(token)) { //Type from token.children[0] // //|-CXXOperatorCallExpr 0x1f38c6b5468 <line:2997:2, line:3005:6> 'CPacket' lvalue '<<' //| |-ImplicitCastExpr 0x1f38c6b5450 <col:3> 'CPacket &(*)(int)' <FunctionToPointerDecay> //| | `-DeclRefExpr 0x1f38c6b5430 <col:3> 'CPacket &(int)' lvalue CXXMethod 0x1f386e73ac8 'operator<<' 'CPacket &(int)' if (TryGetPacketWriteOverloadType(token.children[0], out var typeName)) { Console.Write($"Write type : {typeName} Name: "); } else { Console.WriteLine("Write type not found!"); Debugger.Break(); return; } if (token.children.Count < 2) { Console.WriteLine("Unhandled: children count is smaller than expected!"); Debugger.Break(); return; } var instructionvisitor = new InstructionVisitor(token.children[2]); var executionResult = instructionvisitor.Execute(); if (!executionResult) { Console.WriteLine("Unknown"); var bdy = AstTranslator.GetFunctionBody(token.children[2]); var relevant = token.AsTokenDto(); relevant.Children[1] = new AstTokenDto(); var reser = relevant.SerializeFriendly(); Debugger.Break(); } //if (token.children.Count > 1 && TryGetSimpleWriteFromVar(token.children[2], out var prop)) //{ // Console.Write(prop.Name); // //var callPart = token.children[0].SerializeFriendly(); // //Debugger.Break(); //} //else if (TryGetMethodCallWrite(token.children[2], out var name)) //{ // //Debugger.Break(); // Console.Write(name); //} //else if (TryParseSizeAccessor(token.children[2])) //{ // //Debugger.Break(); //} //else //{ // Console.Write("Unknown"); // var bdy = AstTranslator.GetFunctionBody(token.children[2]); // var relevant = token.AsTokenDto(); // relevant.Children[1] = new AstTokenDto(); // var reser = relevant.SerializeFriendly(); // Debugger.Break(); //} //var accessor = GetChildAccesor(token.children[2]); Console.WriteLine(); } }
protected AstToken ParseTokenDescription(string name, string description, ref AstTokenContext contextFilename) { var token = new AstToken() { name = name }; string[] parameters = this.GetStringArray(description); int parameterStartIndex = 0; string sufix = this.GetSufix(name); switch (sufix) { case "Decl": token.offset = parameters[0]; parameterStartIndex = 1; token.fileContext = parameters[parameterStartIndex]; while (!token.fileContext.StartsWith("<")) { if (token.relationOffset != null) { token.relationOffset = token.relationOffset + " " + parameters[parameterStartIndex] + " " + parameters[parameterStartIndex + 1]; } else { token.relationOffset = parameters[parameterStartIndex] + " " + parameters[parameterStartIndex + 1]; } parameterStartIndex += 2; token.fileContext = parameters[parameterStartIndex]; } token.filePointer = parameters[parameterStartIndex + 1]; parameterStartIndex += 2; break; case "Type": case "Record": case "Typedef": case "Parm": case "Specialization": case "Function": case "Enum": case "Field": case "Alias": case "Comment": token.offset = parameters[0]; parameterStartIndex = 1; break; case "Attr": case "Expr": case "Literal": case "Operator": case "Stmt": case "Cleanups": token.offset = parameters[0]; token.fileContext = parameters[1]; parameterStartIndex = 2; break; case "Data": case "Constructor": case "Assignment": case "Destructor": case "Argument": case "Initializer": case "public": case "private": case "protected": case "virtual": case "<<<NULL>>>": case "Overrides:": case "...": case "array": break; case "original": token.name = name + parameters[0]; token.offset = parameters[1]; parameterStartIndex = 2; break; default: throw new NotImplementedException(name); } token.properties = parameters.Where((value, index) => index >= parameterStartIndex).ToArray(); if (token.fileContext != null) { string fileContext = token.fileContext.Substring(1, token.fileContext.Length - 2); if (fileContext.Contains(",")) { fileContext = fileContext.Substring(0, fileContext.IndexOf(",")); } string[] parts = fileContext.Split(':'); if (parts[0] == "<invalid sloc>") { contextFilename.sourceFile = "<invalid sloc>"; contextFilename.column = 0; contextFilename.line = 0; } else if (parts[0] == "<built-in>") { contextFilename.sourceFile = "<built-in>"; contextFilename.line = int.Parse(parts[1]); contextFilename.column = int.Parse(parts[2]); } else if (parts[0] == "<scratch space>") { contextFilename.sourceFile = "<built-in>"; contextFilename.line = int.Parse(parts[1]); contextFilename.column = int.Parse(parts[2]); } else if (parts[0] == "line") { contextFilename.line = int.Parse(parts[1]); contextFilename.column = int.Parse(parts[2]); } else if (parts[0] == "col") { contextFilename.column = int.Parse(parts[1]); } else { contextFilename.sourceFile = parts[0]; contextFilename.line = int.Parse(parts[1]); contextFilename.column = int.Parse(parts[2]); } token.context = new AstTokenContext() { column = contextFilename.column, line = contextFilename.line, sourceFile = contextFilename.sourceFile }; } // remove service properties if (token.properties.Length > 0 && token.properties[0] == "implicit") { token.attributes = token.attributes.Concat(new string[] { token.properties[0] }).ToArray(); token.properties = token.properties.Where((value, index) => index >= 1).ToArray(); } if (token.properties.Length > 0 && token.properties[0] == "used") { token.attributes = token.attributes.Concat(new string[] { token.properties[0] }).ToArray(); token.properties = token.properties.Where((value, index) => index >= 1).ToArray(); } if (token.properties.Length > 0 && token.properties[0] == "referenced") { token.attributes = token.attributes.Concat(new string[] { token.properties[0] }).ToArray(); token.properties = token.properties.Where((value, index) => index >= 1).ToArray(); } if (token.properties.Length > 0 && token.properties[token.properties.Length - 1] == "cinit") { token.attributes = token.attributes.Concat(new string[] { token.properties[token.properties.Length - 1] }).ToArray(); token.properties = token.properties.Where((value, index) => index < token.properties.Length - 1).ToArray(); } if (token.properties.Length > 0 && token.properties[token.properties.Length - 1] == "extern") { token.attributes = token.attributes.Concat(new string[] { token.properties[token.properties.Length - 1] }).ToArray(); token.properties = token.properties.Where((value, index) => index < token.properties.Length - 1).ToArray(); } if (token.properties.Length > 0 && token.properties[token.properties.Length - 1] == "callinit") { token.attributes = token.attributes.Concat(new string[] { token.properties[token.properties.Length - 1] }).ToArray(); token.properties = token.properties.Where((value, index) => index < token.properties.Length - 1).ToArray(); } if (token.properties.Length > 0 && token.properties[token.properties.Length - 1] == "static") { token.attributes = token.attributes.Concat(new string[] { token.properties[token.properties.Length - 1] }).ToArray(); token.properties = token.properties.Where((value, index) => index < token.properties.Length - 1).ToArray(); } if (token.properties.Length > 0 && token.properties[token.properties.Length - 1] == "definition") { token.attributes = token.attributes.Concat(new string[] { token.properties[token.properties.Length - 1] }).ToArray(); token.properties = token.properties.Where((value, index) => index < token.properties.Length - 1).ToArray(); } if (token.properties.Length > 0 && token.properties[token.properties.Length - 1] == "nrvo") { token.attributes = token.attributes.Concat(new string[] { token.properties[token.properties.Length - 1] }).ToArray(); token.properties = token.properties.Where((value, index) => index < token.properties.Length - 1).ToArray(); } return(token); }
public AstTextFile(string astDumpPath) { this.filename = astDumpPath; string[] lines = System.IO.File.ReadAllLines(astDumpPath); rootTokens = new System.Collections.Generic.List <AstToken>(); System.Collections.Generic.List <AstToken> currentTokens = new System.Collections.Generic.List <AstToken>(); AstTokenContext contextFilename = new AstTokenContext() { sourceFile = "<invalid sloc>", column = 0, line = 0 }; foreach (var line in lines) { int lineDepth = 0; int tokenStart = -1; int tokenEnd = -1; for (int i = 0; i < line.Length; i += 2) { if (line[i] == '|' || line[i] == '`' || line[i] == ' ' || line[i] == '-') { lineDepth++; continue; } else { tokenStart = i; break; } } tokenEnd = line.IndexOf(' ', tokenStart); string token = ""; string declaration = ""; if (tokenEnd == -1) { token = line.Substring(tokenStart, line.Length - tokenStart); } else { token = line.Substring(tokenStart, tokenEnd - tokenStart); declaration = line.Substring(tokenEnd + 1); } AstToken astToken = this.ParseTokenDescription(token, declaration, ref contextFilename); if (lineDepth == 0) { rootTokens.Add(astToken); if (currentTokens.Count == 0) { currentTokens.Add(astToken); } else { currentTokens[0] = astToken; } } else { if (lineDepth >= currentTokens.Count) { currentTokens.Add(astToken); } else { currentTokens[lineDepth] = astToken; } currentTokens[lineDepth - 1].children.Add(astToken); astToken.parent = currentTokens[lineDepth - 1]; } } }
// reference accessor (pInfo->wNpcID) SendCS_AUCTIONREG_REQ /* | | | | | | | | `-ImplicitCastExpr 0x1f38c61d1e8 <line:2201:6, col:13> 'WORD':'unsigned short' <LValueToRValue> | | | | | | | | `-MemberExpr 0x1f38c61c578 <col:6, col:13> 'WORD':'unsigned short' lvalue ->wNpcID 0x1f38a41b8f0 | | | | | | | | `-ImplicitCastExpr 0x1f38c61c560 <col:6> 'LPTAUCTIONREGINFO':'struct tagTAUCTIONREGINFO *' <LValueToRValue> | | | | | | | | `-DeclRefExpr 0x1f38c61c540 <col:6> 'LPTAUCTIONREGINFO':'struct tagTAUCTIONREGINFO *' lvalue ParmVar 0x1f38c61c1a0 'pInfo' 'LPTAUCTIONREGINFO':'struct tagTAUCTIONREGINFO *' */ // Size Accessor /* `-CXXFunctionalCastExpr 0x1f38c6b7060 <line:3008:6, col:25> 'BYTE':'unsigned char' functional cast to BYTE <NoOp> | | `-ImplicitCastExpr 0x1f38c6b7048 <col:11, col:24> 'BYTE':'unsigned char' <IntegralCast> part_of_explicit_cast | | `-CXXMemberCallExpr 0x1f38c6b6ff8 <col:11, col:24> 'std::vector<tagTSKILLTARGET *, std::allocator<tagTSKILLTARGET *>>::size_type':'unsigned long long' | | `-MemberExpr 0x1f38c6b6fc8 <col:11, col:19> '<bound member function type>' .size 0x1f38a7d6710 | | `-DeclRefExpr 0x1f38c6b6fa8 <col:11> 'const VTSKILLTARGET':'const std::vector<tagTSKILLTARGET *, std::allocator<tagTSKILLTARGET *>>' lvalue ParmVar 0x1f38c6ae888 'vTarget' 'const VTSKILLTARGET &' */ //DeclRefExpr /* [0] "const VTSKILLTARGET':'const std::vector<tagTSKILLTARGET *, std::allocator<tagTSKILLTARGET *>>" string * [1] "lvalue" string * [2] "ParmVar" string * [3] "0x1f38c6ae888" string * [4] "vTarget" string * [5] "const VTSKILLTARGET &" string */ //MemberExpr /* [0] "<bound member function type>" string * [1] ".size" string * [2] "0x1f38a7d6710" string */ //Parses size accessor like Vector.size() and converts it to Array.Length; private bool TryParseSizeAccessor(AstToken token) { var found = token.children.Select(TryParseSizeAccessor).FirstOrDefault(x => x == true); if (token.children.Any() && !found) { return(false); } switch (token.Type) { case AstType.CXXFunctionalCastExpr: case AstType.ImplicitCastExpr: break; case AstType.CXXMemberCallExpr: break; case AstType.MemberExpr: if (token.properties[1].EndsWith("size")) { Console.Write(".Length"); return(true); } var toWrite = token.properties[1] == "lvalue" ? token.properties[2] : token.properties[1]; Console.Write($" {toWrite}"); return(true); //Debugger.Break(); break; case AstType.DeclRefExpr: var vectorRegex = new Regex("std\\:\\:vector\\<(.*?) .*?\\,"); var matches = vectorRegex.Match(token.properties[0]); if (matches.Success) { //its a vector var structName = matches.Groups[1].Value.TrimStart("tag"); Console.Write($"Vector found: {structName}"); } else { var structTypeRegex = new Regex("':'(.*?) (.*?) "); var match = structTypeRegex.Match(token.properties[0]); if (match.Success) { Console.Write($"{match.Groups[1].Value} found: {match.Groups[2].Value}"); } } Console.Write($" Name: {token.properties[4]}"); //Debugger.Break(); return(true); break; default: return(found); } return(found); }