Beispiel #1
0
        public static Symbol LookupSymbol(Node tree, string identifier, bool strongonly)
        {
            Match ident = identifierRegex.Match(identifier);

            if (!ident.Success)
            {
                throw new Exception("Invalid identifier specified " + identifier);
            }

            if (!identifier.Contains("::"))
            {
                Node classNode = FindNode(tree, ident.Captures[0].Value);

                if (classNode == null)
                {
                    if (strongonly)
                    {
                        throw new Exception("Invalid weak symbol " + identifier);
                    }
                    else
                    {
                        return new WeakSymbol(identifier);
                    }
                }
                else
                {
                    return new StrongSymbol(classNode);
                }
            }
            else
            {
                ident = fullIdentRegex.Match(identifier);

                if (!ident.Success)
                {
                    throw new Exception("Couldn't parse full identifier");
                }

                Node classNode = FindNode(tree, ident.Groups["class"].Value);

                if (classNode == null)
                {
                    throw new Exception("Invalid class in identifier " + identifier);
                }

                Node propNode = FindNode(classNode, ident.Groups["name"].Value);

                if (propNode == null)
                {
                    throw new Exception("Invalid property in identifier " + identifier);
                }

                return new StrongSymbol(classNode, propNode);
            }
            
            throw new Exception("Invalid symbol");
        }
Beispiel #2
0
 public void EmitNode(Node n, StringBuilder sb, int level)
 {
     if (n is ClassNode)
     {
         EmitClassNode(n as ClassNode, sb, level);
     }
     else if (n is EnumNode)
     {
         EmitEnumNode(n as EnumNode, sb);
     }
 }
Beispiel #3
0
 public void EmitEnums(Node root, StringBuilder sb)
 {
     sb.AppendLine("// Generated code");
     sb.AppendLine("// DO NOT EDIT");
     sb.AppendLine();
     sb.AppendLine("package internal");
     sb.AppendLine();
     foreach (Node n in root.childNodes) {
         EmitEnumNode(n as EnumNode, sb);
     }
 }
Beispiel #4
0
        // single level
        private static Node FindNode(Node tree, string symbol)
        {
            foreach (Node child in tree.childNodes)
            {
                if (child.Name == symbol)
                {
                    return child;
                }
            }

            return null;
        }
Beispiel #5
0
 public void EmitEnums(Node root, StringBuilder sb)
 {
     sb.AppendLine("// Generated code");
     sb.AppendLine("// DO NOT EDIT");
     sb.AppendLine();
     sb.AppendLine("package steamlang");
     sb.AppendLine();
     sb.AppendLine("import (");
     sb.AppendLine("    \"strings\"");
     sb.AppendLine("    \"sort\"");
     sb.AppendLine("    \"fmt\"");
     sb.AppendLine(")");
     sb.AppendLine();
     foreach (Node n in root.childNodes) {
         EmitEnumNode(n as EnumNode, sb);
     }
 }
Beispiel #6
0
        public void EmitClasses(Node root, StringBuilder sb)
        {
            sb.AppendLine("// Generated code");
            sb.AppendLine("// DO NOT EDIT");
            sb.AppendLine();
            sb.AppendLine("package internal");
            sb.AppendLine();
            sb.AppendLine("import (");
            sb.AppendLine("    \"io\"");
            sb.AppendLine("    \"encoding/binary\"");
            sb.AppendLine("    \"code.google.com/p/goprotobuf/proto\"");
            sb.AppendLine("    . \"github.com/manveru/go-steam/steamid\"");
            sb.AppendLine(")");
            sb.AppendLine();

            foreach (Node n in root.childNodes) {
                EmitClassNode(n as ClassNode, sb);
            }
        }
Beispiel #7
0
        public void EmitClasses(Node root, StringBuilder sb)
        {
            sb.AppendLine("// Generated code");
            sb.AppendLine("// DO NOT EDIT");
            sb.AppendLine();
            sb.AppendLine("package steamlang");
            sb.AppendLine();
            sb.AppendLine("import (");
            sb.AppendLine("    \"io\"");
            sb.AppendLine("    \"encoding/binary\"");
            sb.AppendLine("    \"github.com/golang/protobuf/proto\"");
            sb.AppendLine("    \"github.com/Philipp15b/go-steam/steamid\"");
            sb.AppendLine("    \"github.com/Philipp15b/go-steam/rwu\"");
            sb.AppendLine("   . \"github.com/Philipp15b/go-steam/internal/protobuf\"");
            sb.AppendLine(")");
            sb.AppendLine();

            foreach (Node n in root.childNodes) {
                EmitClassNode(n as ClassNode, sb);
            }
        }
Beispiel #8
0
        public static void Main(string[] args)
        {
            if (args.Length < 2) {
                Console.WriteLine("Must have at least two parameters: SteamKit root path and output path!");
                return;
            }

            string steamKitPath = Path.GetFullPath(args[0]);
            string languagePath = Path.Combine(steamKitPath, "Resources", "SteamLanguage");
            string outputPath = Path.GetFullPath(args[1]);

            Environment.CurrentDirectory = languagePath;

            var codeGen = new GoGen(args.Length > 2 && args[2] == "debug");

            Queue<Token> tokenList = LanguageParser.TokenizeString(File.ReadAllText("steammsg.steamd"));

            Node root = TokenAnalyzer.Analyze(tokenList);

            Node rootEnumNode = new Node();
            Node rootMessageNode = new Node();

            rootEnumNode.childNodes.AddRange(root.childNodes.Where(n => n is EnumNode));
            rootMessageNode.childNodes.AddRange(root.childNodes.Where(n => n is ClassNode));

            StringBuilder enumBuilder = new StringBuilder();
            StringBuilder messageBuilder = new StringBuilder();

            codeGen.EmitEnums(rootEnumNode, enumBuilder);
            codeGen.EmitClasses(rootMessageNode, messageBuilder);

            string outputEnumFile = Path.Combine(outputPath, "enums.go");
            string outputMessageFile = Path.Combine(outputPath, "messages.go");

            Directory.CreateDirectory(Path.GetDirectoryName(outputEnumFile));

            File.WriteAllText(Path.Combine(steamKitPath, outputEnumFile), enumBuilder.ToString());
            File.WriteAllText(Path.Combine(steamKitPath, outputMessageFile), messageBuilder.ToString());
        }
Beispiel #9
0
        public static Node Analyze( Queue<Token> tokens )
        {
            Node root = new Node();

            while (tokens.Count > 0)
            {
                Token cur = tokens.Dequeue();

                switch (cur.Name)
                {
                    case "EOF":
                        break;
                    case "preprocess":
                        Token text = Expect(tokens, "string");

                        if (cur.Value == "import")
                        {
                            Queue<Token> parentTokens = LanguageParser.TokenizeString( File.ReadAllText( text.Value ) );

                            Node newRoot = Analyze( parentTokens );

                            foreach (Node child in newRoot.childNodes)
                            {
                                root.childNodes.Add(child);
                            }
                        }
                        break;
                    case "identifier":
                        switch (cur.Value)
                        {
                            case "class":
                                {
                                    Token name = Expect(tokens, "identifier");
                                    Token ident = null, parent = null;

                                    Token op1 = Optional(tokens, "operator", "<");
                                    if (op1 != null)
                                    {
                                        ident = Expect(tokens, "identifier");
                                        Token op2 = Expect(tokens, "operator", ">");
                                    }

                                    Token expect = Optional(tokens, "identifier", "expects");
                                    if (expect != null)
                                    {
                                        parent = Expect(tokens, "identifier");
                                    }

                                    ClassNode cnode = new ClassNode();
                                    cnode.Name = name.Value;

                                    if (ident != null)
                                    {
                                        cnode.Ident = SymbolLocator.LookupSymbol(root, ident.Value, false);
                                    }

                                    if (parent != null)
                                    {
                                        //cnode.Parent = SymbolLocator.LookupSymbol(root, parent.Value, true);
                                    }

                                    root.childNodes.Add(cnode);
                                    ParseInnerScope(tokens, cnode, root);
                                }
                                break;
                            case "enum":
                                {
                                    Token name = Expect(tokens, "identifier");
                                    Token datatype = null;

                                    Token op1 = Optional(tokens, "operator", "<");
                                    if (op1 != null)
                                    {
                                        datatype = Expect(tokens, "identifier");
                                        Token op2 = Expect(tokens, "operator", ">");
                                    }

                                    Token flag = Optional( tokens, "identifier", "flags" );

                                    EnumNode enode = new EnumNode();
                                    enode.Name = name.Value;

                                    if ( flag != null )
                                    {
                                        enode.Flags = flag.Value;
                                    }

                                    if (datatype != null)
                                    {
                                        enode.Type = SymbolLocator.LookupSymbol(root, datatype.Value, false);
                                    }


                                    root.childNodes.Add(enode);
                                    ParseInnerScope(tokens, enode, root);
                                }
                                break;
                        }
                        break;
                }
            }

            return root;
        }
Beispiel #10
0
        private static void ParseInnerScope(Queue<Token> tokens, Node parent, Node root)
        {
            Token scope1 = Expect(tokens, "operator", "{");
            Token scope2 = Optional(tokens, "operator", "}");

            while (scope2 == null)
            {
                PropNode pnode = new PropNode();

                Token t1 = tokens.Dequeue();

                Token t1op1 = Optional(tokens, "operator", "<");
                Token flagop = null;

                if (t1op1 != null)
                {
                    flagop = Expect(tokens, "identifier");
                    Token t1op2 = Expect(tokens, "operator", ">");

                    pnode.FlagsOpt = flagop.Value;
                }

                Token t2 = Optional(tokens, "identifier");
                Token t3 = Optional(tokens, "identifier");

                if (t3 != null)
                {
                    pnode.Name = t3.Value;
                    pnode.Type = SymbolLocator.LookupSymbol(root, t2.Value, false);
                    pnode.Flags = t1.Value;
                }
                else if (t2 != null)
                {
                    pnode.Name = t2.Value;
                    pnode.Type = SymbolLocator.LookupSymbol(root, t1.Value, false);
                }
                else
                {
                    pnode.Name = t1.Value;
                }

                Token defop = Optional(tokens, "operator", "=");

                if ( defop != null )
                {
                    while ( true )
                    {
                        Token value = tokens.Dequeue();
                        pnode.Default.Add( SymbolLocator.LookupSymbol( root, value.Value, false ) );

                        if ( Optional( tokens, "operator", "|" ) != null )
                            continue;

                        Expect( tokens, "terminator", ";" );
                        break;
                    }
                }
                else
                {
                    Expect( tokens, "terminator", ";" );
                }

                Token obsolete = Optional( tokens, "identifier", "obsolete" );
                if ( obsolete != null )
                {
                    pnode.Obsolete = "";

                    Token obsoleteReason = Optional( tokens, "string" );

                    if ( obsoleteReason != null )
                        pnode.Obsolete = obsoleteReason.Value;
                }

                parent.childNodes.Add(pnode);

                scope2 = Optional(tokens, "operator", "}");
            }
        }
Beispiel #11
0
        public static void EmitCode(Node root, ICodeGen gen, StringBuilder sb, string nspace, bool supportsGC, bool internalFile )
        {
            gen.EmitNamespace(sb, false, nspace);

            int level = 0;
            if (gen.SupportsNamespace())
                level = 1;

            if ( internalFile )
                gen.EmitSerialBase( sb, level, supportsGC );

            foreach (Node n in root.childNodes)
            {
                gen.EmitNode(n, sb, level);
            }

            gen.EmitNamespace(sb, true, nspace);
        }
Beispiel #12
0
 public StrongSymbol(Node classNode, Node prop)
 {
     Class = classNode;
     Prop = prop;
 }
Beispiel #13
0
 public StrongSymbol(Node classNode)
 {
     Class = classNode;
 }
Beispiel #14
0
        private static void ParseInnerScope(Queue<Token> tokens, Node parent, Node root)
        {
            Token scope1 = Expect(tokens, "operator", "{");
            Token scope2 = Optional(tokens, "operator", "}");

            while (scope2 == null)
            {
                PropNode pnode = new PropNode();

                Token t1 = tokens.Dequeue();

                Token t1op1 = Optional(tokens, "operator", "<");
                Token flagop = null;

                if (t1op1 != null)
                {
                    flagop = Expect(tokens, "identifier");
                    Token t1op2 = Expect(tokens, "operator", ">");

                    pnode.FlagsOpt = flagop.Value;
                }

                Token t2 = Optional(tokens, "identifier");
                Token t3 = Optional(tokens, "identifier");

                if (t3 != null)
                {
                    pnode.Name = t3.Value;
                    pnode.Type = SymbolLocator.LookupSymbol(root, t2.Value, false);
                    pnode.Flags = t1.Value;
                }
                else if (t2 != null)
                {
                    pnode.Name = t2.Value;
                    pnode.Type = SymbolLocator.LookupSymbol(root, t1.Value, false);
                }
                else
                {
                    pnode.Name = t1.Value;
                }

                Token defop = Optional(tokens, "operator", "=");

                if (defop != null)
                {
                    Token value = tokens.Dequeue();
                    pnode.Default = SymbolLocator.LookupSymbol(root, value.Value, false);
                }

                Expect(tokens, "terminator", ";");

                parent.childNodes.Add(pnode);

                scope2 = Optional(tokens, "operator", "}");
            }
        }