diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 0f3cdc8f81..2df3ad0b59 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,189 +3,189 @@ "isRoot": true, "tools": { "trcaret": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trcaret" ], "rollForward": false }, "trcover": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trcover" ], "rollForward": false }, "trgen": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trgen" ], "rollForward": false }, "trglob": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trglob" ], "rollForward": false }, "triconv": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "triconv" ], "rollForward": false }, "trparse": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trparse" ], "rollForward": false }, "trquery": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trquery" ], "rollForward": false }, "trtext": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trtext" ], "rollForward": false }, "trwdog": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trwdog" ], "rollForward": false }, "trxgrep": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trxgrep" ], "rollForward": false }, "trxml": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trxml" ], "rollForward": false }, "trxml2": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trxml2" ], "rollForward": false }, "trclonereplace": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trclonereplace" ], "rollForward": false }, "trcombine": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trcombine" ], "rollForward": false }, "trconvert": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trconvert" ], "rollForward": false }, "trfoldlit": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trfoldlit" ], "rollForward": false }, "trgenvsc": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trgenvsc" ], "rollForward": false }, "tritext": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "tritext" ], "rollForward": false }, "trjson": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trjson" ], "rollForward": false }, "trperf": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trperf" ], "rollForward": false }, "trrename": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trrename" ], "rollForward": false }, "trsort": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trsort" ], "rollForward": false }, "trsplit": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trsplit" ], "rollForward": false }, "trsponge": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trsponge" ], "rollForward": false }, "trtokens": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trtokens" ], "rollForward": false }, "trtree": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trtree" ], "rollForward": false }, "trunfold": { - "version": "0.23.17", + "version": "0.23.18", "commands": [ "trunfold" ], diff --git a/golang/CSharp/Func.cs b/golang/CSharp/Func.cs new file mode 100644 index 0000000000..b294b320a5 --- /dev/null +++ b/golang/CSharp/Func.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +public class Func +{ + public ulong Entry { get; set; } + public Sym Sym { get; set; } + public ulong End { get; set; } + public List Params { get; set; } = new List(); + public List Locals { get; set; } = new List(); + public int FrameSize { get; set; } + public Obj Obj { get; set; } +} diff --git a/golang/CSharp/GoClassification.cs b/golang/CSharp/GoClassification.cs new file mode 100644 index 0000000000..96dfcae17e --- /dev/null +++ b/golang/CSharp/GoClassification.cs @@ -0,0 +1,18 @@ +public enum GoClassification { + GoVariable, + GoField, + GoParameterType, + GoArrayType, + GoStructType, + GoPointerType, + GoFunctionType, + GoInterfaceType, + GoSliceType, + GoMapType, + GoChannelType, + GoPackage, + GoMethod, + GoScope, + GoBlock, + GoBasicType, +}; diff --git a/golang/CSharp/GoParserBase.cs b/golang/CSharp/GoParserBase.cs index ecc946c023..408a8a0f39 100644 --- a/golang/CSharp/GoParserBase.cs +++ b/golang/CSharp/GoParserBase.cs @@ -1,13 +1,15 @@ +using Antlr4.Runtime; +using Antlr4.Runtime.Tree; using System; using System.Collections.Generic; using System.IO; using System.Linq; -using Antlr4.Runtime; public abstract class GoParserBase : Parser { - const bool debug = false; - HashSet table = new HashSet(); + bool debug = false; + SymbolTable symbolTable = new SymbolTable(); + Dictionary ContextToSymbolMap = new Dictionary(); protected GoParserBase(ITokenStream input) : base(input) @@ -27,9 +29,18 @@ private ITokenStream tokenStream } } - protected void myreset() + protected void DefinePackageClause() { - table = new HashSet(); + // Grab package name, and start a scope. + var ctx = this.Context; + var tctx = (GoParser.PackageClauseContext) ctx; + var identifier = tctx.packageName().identifier(); + var name = identifier.IDENTIFIER().GetText(); + var newScope = new Symbol() { Name = "", Classification = GoClassification.GoPackage }; + var sym = new Symbol() { Name = name, Type = newScope, Classification = GoClassification.GoPackage }; + symbolTable.Define(sym); + symbolTable.EnterScope(newScope); + if (debug) System.Console.WriteLine("defined " + sym); } protected bool closingBracket() @@ -41,61 +52,70 @@ protected bool closingBracket() public bool isNotReceive() { var la = tokenStream.LT(2); - return la.Type != GoParser.RECEIVE; + var result = la.Type != GoParser.RECEIVE; + if (debug) System.Console.WriteLine("isNotReceive returning " + result); + return result; } - public void addImportSpec() + public void DefineImportSpec() { var ctx = this.Context; var count = ctx.ChildCount; var importSpec = ctx as GoParser.ImportSpecContext; if (importSpec == null) return; var packageName = importSpec.packageName(); + var parent_scope = symbolTable.CurrentScope().Parent; if (packageName != null) { var name = packageName.GetText(); - if (debug) System.Console.WriteLine("Entering " + name); - table.Add(name); + // Import declarations occur after the packageClause. + // So, add the package to the *parent* of the + // packageClause, i.e., the global scope. + var newScope = new Symbol() { Name = "", Classification = GoClassification.GoPackage }; + var symbol = new Symbol() { Name = name, Type = newScope, Classification = GoClassification.GoPackage}; + symbolTable.DefineInScope(parent_scope, symbol); + if (debug) System.Console.WriteLine("defined " + symbol); } else { - var name = importSpec.importPath().GetText(); - name = name.Replace("\"", ""); - name = name.Replace("\\", "/"); - string[] pathArr = name.Split('/'); + var fname = importSpec.importPath().GetText(); + fname = fname.Replace("\"", ""); + fname = fname.Replace("\\", "/"); + string[] pathArr = fname.Split('/'); string[] fileArr = pathArr.Last().Split('.'); - string fileName = fileArr.Last().ToString(); - if (debug) System.Console.WriteLine("Entering " + fileName); - table.Add(fileName); + string name = fileArr.Last().ToString(); + var newScope = new Symbol() { Name = "", Classification = GoClassification.GoPackage }; + var symbol = new Symbol() { Name = name, Type = newScope, Classification = GoClassification.GoPackage}; + symbolTable.DefineInScope(parent_scope, symbol); + if (debug) System.Console.WriteLine("defined " + symbol); } } public bool isOperand() { var la = tokenStream.LT(1); + if (debug) System.Console.WriteLine("testing isOperand for " + la.Text); if (la.Text == "err") return true; - bool result = true; if (la.Type != GoParser.IDENTIFIER) { - if (debug) System.Console.WriteLine("isOperand Returning " + result + " for " + la); - return result; + if (debug) System.Console.WriteLine("isOperand Returning " + true + " for " + la); + return true; } - result = table.Contains(la.Text); + var symbol = symbolTable.Resolve(la.Text); + var result = symbol != null; var la2 = tokenStream.LT(2); // If it's not followed by a '.', then it really should be // considered as operand. if (la2.Type != GoParser.DOT) { - result = true; - if (debug) System.Console.WriteLine("isOperand Returning " + result + " for " + la); - return result; + if (debug) System.Console.WriteLine("isOperand Returning " + true + " for " + la); + return true; } // If it's followed by '.', and then followed by '(', then // it is a typeAssertion, and so la must be an operand. var la3 = tokenStream.LT(3); if (la3.Type == GoParser.L_PAREN) { - result = true; - if (debug) System.Console.WriteLine("isOperand Returning " + result + " for " + la); - return result; + if (debug) System.Console.WriteLine("isOperand Returning " + true + " for " + la); + return true; } if (debug) System.Console.WriteLine("isOperand Returning " + result + " for " + la); return result; @@ -123,8 +143,200 @@ public bool isMethodExpr() if (debug) System.Console.WriteLine("isMethodExpr Returning " + result + " for " + la); return result; } - result = ! table.Contains(la.Text); + result = symbolTable.Resolve(la.Text) == null; if (debug) System.Console.WriteLine("isMethodExpr Returning " + result + " for " + la); return result; } + + public void EnterFunctionDecl() + { + var ctx = this.Context.Parent; + var function_decl = (GoParser.FunctionDeclContext) ctx; + var id = function_decl.IDENTIFIER(); + var id_name = id.GetText(); + var sym = new Symbol() { Name = id_name, Classification = GoClassification.GoFunctionType }; + symbolTable.Define(sym); + if (debug) System.Console.WriteLine("defined " + sym); + var newScope = new Symbol() { Name = "", Classification = GoClassification.GoFunctionType }; + symbolTable.EnterScope(newScope); + } + + public void ExitStruct() + { + if (debug) System.Console.WriteLine("ExitStruct"); + symbolTable.ExitScope(); + } + + public void ExitFunctionDecl() + { + if (debug) System.Console.WriteLine("ExitFunctionDecl"); + symbolTable.ExitScope(); + } + + public void EnterInterface() + { + var newScope = new Symbol() { Name = "", Classification = GoClassification.GoInterfaceType }; + if (debug) System.Console.WriteLine("EnterInterface " + newScope); + symbolTable.EnterScope(newScope); + } + + public void EnterStruct() + { + var newScope = new Symbol() { Name = "", Classification = GoClassification.GoStructType }; + if (debug) System.Console.WriteLine("EnterStruct " + newScope); + symbolTable.EnterScope(newScope); + } + + public void EnterBlock() + { + var newScope = new Symbol() { Name = "", Classification = GoClassification.GoBlock }; + if (debug) System.Console.WriteLine("EnterBlock " + newScope); + symbolTable.EnterScope(newScope); + } + + public void ExitScope() + { + if (debug) System.Console.WriteLine("ExitScope " + symbolTable.CurrentScope()); + symbolTable.ExitScope(); + } + + public void ExitInterface() + { + if (debug) System.Console.WriteLine("ExitInterface " + symbolTable.CurrentScope()); + symbolTable.ExitScope(); + } + + public void ShortVarDecl() + { + var ctx = this.Context; + var tctx = (GoParser.ShortVarDeclContext) ctx; + var id_list = tctx.identifierList(); + var ids = id_list.IDENTIFIER(); + foreach (var id in ids) + { + var id_name = id.GetText(); + var sym = new Symbol() { Name = id_name, Classification = GoClassification.GoVariable }; + symbolTable.Define(sym); + if (debug) System.Console.WriteLine("defined " + sym); + } + } + + public void DefineInterfaceType() + { + var ctx = this.Context; + var tctx = (GoParser.InterfaceTypeContext) ctx; + var method_specs = tctx.methodSpec(); + var symbol = symbolTable.CurrentScope(); + foreach (var method_spec in method_specs) + { + var name = method_spec.IDENTIFIER().GetText(); + var method = new Symbol() { Name = name, Classification = GoClassification.GoMethod }; + symbolTable.Define(method); + method.Parent = symbol; + this.ContextToSymbolMap[method_spec] = method; + if (debug) System.Console.WriteLine("defined " + method); + // Assert parent of method is in interface scope. + if (method.Parent.Classification != GoClassification.GoInterfaceType) + throw new Exception("interface type definition error."); + } + // Bind the interface type to parent. + this.ContextToSymbolMap[ctx] = symbol; + } + + public void DefineStructType() + { + var ctx = this.Context; + var tctx = (GoParser.StructTypeContext) ctx; + // Bind the interface type to parent. + var symbol = symbolTable.CurrentScope(); + this.ContextToSymbolMap[ctx] = symbol; + } + + public void AssignChildToParent(int c) + { + var ctx = this.Context; + var child = ctx.GetChild(c); + if (debug) System.Console.WriteLine("assigning to " + ctx + " from " + child); + var found = this.ContextToSymbolMap.TryGetValue(child, out Symbol symbol); + if (symbol != null) + this.ContextToSymbolMap[ctx] = symbol; + } + + public void BindTypeToName() + { + var ctx = this.Context; + var type_def = (GoParser.TypeDefContext) ctx; + var type = this.ContextToSymbolMap.TryGetValue(type_def.type_(), + out Symbol symbol); + var name = type_def.IDENTIFIER().GetText(); + if (symbol != null) + { + // BIND name to TYPE. + var classification = symbol.Classification; + var new_symbol = new Symbol() { Name = name, Type = symbol, Classification = classification }; + symbolTable.Define(new_symbol); + if (debug) System.Console.WriteLine("defined " + new_symbol); + } + } + + public void AddParameterDecl() + { + var ctx = this.Context; + var tctx = (GoParser.ParameterDeclContext) ctx; + var identifier_list = tctx.identifierList(); + if (identifier_list == null) return; + var identifiers = identifier_list.IDENTIFIER(); + foreach (var identifier in identifiers) + { + var name = identifier.GetText(); + var variable = new Symbol() { Name = name, Classification = GoClassification.GoVariable }; + symbolTable.Define(variable); + if (debug) System.Console.WriteLine("defined " + variable); + } + } + + public bool IsType() + { + var la = tokenStream.LT(1); + /* Defer to parser for certain types. */ + if (la.Type == GoParser.CHAN) + { + if (debug) System.Console.WriteLine("IsType testing " + la.Text + " return " + true); + return true; + } + if (la.Type == GoParser.L_BRACKET) + { + if (debug) System.Console.WriteLine("IsType testing " + la.Text + " return " + true); + return true; + } + if (la.Type == GoParser.MAP) + { + if (debug) System.Console.WriteLine("IsType testing " + la.Text + " return " + true); + return true; + } + var id = la.Text; + var sym = symbolTable.Resolve(id); + if (sym == null) + { + if (debug) System.Console.WriteLine("IsType testing " + la.Text + " return " + false); + return false; + } + bool is_type = false; + switch (sym.Classification) + { + case GoClassification.GoParameterType: + case GoClassification.GoArrayType: + case GoClassification.GoStructType: + case GoClassification.GoPointerType: + case GoClassification.GoFunctionType: + case GoClassification.GoInterfaceType: + case GoClassification.GoSliceType: + case GoClassification.GoMapType: + case GoClassification.GoChannelType: + is_type = true; + break; + } + if (debug) System.Console.WriteLine("testing " + sym + " return " + is_type); + return is_type; + } } diff --git a/golang/CSharp/Obj.cs b/golang/CSharp/Obj.cs new file mode 100644 index 0000000000..6225c16f03 --- /dev/null +++ b/golang/CSharp/Obj.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +public class Obj +{ + public List Funcs { get; set; } = new List(); + public List Paths { get; set; } = new List(); +} + diff --git a/golang/CSharp/Sym.cs b/golang/CSharp/Sym.cs new file mode 100644 index 0000000000..d162c593af --- /dev/null +++ b/golang/CSharp/Sym.cs @@ -0,0 +1,8 @@ +public class Sym +{ + public ulong Value { get; set; } + public byte Type { get; set; } + public string Name { get; set; } + public ulong GoType { get; set; } + public Func Func { get; set; } +} diff --git a/golang/CSharp/Symbol.cs b/golang/CSharp/Symbol.cs new file mode 100644 index 0000000000..f405142840 --- /dev/null +++ b/golang/CSharp/Symbol.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; + +public class Symbol { + public string Name { get; set; } + public Symbol Type { get; set; } + public GoClassification Classification { get; set; } + public Dictionary Members { get; } = new(); + public Symbol Parent { get; set; } + + public override string ToString() + { + return Name + + (Type != null ? (" (with type " + Type.ToString() + ")") : "") + + (Parent != null ? (" of " + Parent.ToString()) : ""); + } + + public static Symbol Go_bool = new Symbol() { Name = "bool", Classification = GoClassification.GoBasicType }; + public static Symbol Go_uint8 = new Symbol() { Name = "uint8", Classification = GoClassification.GoBasicType }; + public static Symbol Go_uint16 = new Symbol() { Name = "uint16", Classification = GoClassification.GoBasicType }; + public static Symbol Go_uint32 = new Symbol() { Name = "uint32", Classification = GoClassification.GoBasicType }; + public static Symbol Go_uint64 = new Symbol() { Name = "uint64", Classification = GoClassification.GoBasicType }; + public static Symbol Go_int8 = new Symbol() { Name = "int8", Classification = GoClassification.GoBasicType }; + public static Symbol Go_int16 = new Symbol() { Name = "int16", Classification = GoClassification.GoBasicType }; + public static Symbol Go_int32 = new Symbol() { Name = "int32", Classification = GoClassification.GoBasicType }; + public static Symbol Go_int64 = new Symbol() { Name = "int64", Classification = GoClassification.GoBasicType }; + public static Symbol Go_float32 = new Symbol() { Name = "float32", Classification = GoClassification.GoBasicType }; + public static Symbol Go_float64 = new Symbol() { Name = "float64", Classification = GoClassification.GoBasicType }; + public static Symbol Go_complex64 = new Symbol() { Name = "complex64", Classification = GoClassification.GoBasicType }; + public static Symbol Go_complex128 = new Symbol() { Name = "complex128", Classification = GoClassification.GoBasicType }; + public static Symbol Go_byte = new Symbol() { Name = "byte", Classification = GoClassification.GoBasicType }; + public static Symbol Go_rune = new Symbol() { Name = "rune", Classification = GoClassification.GoBasicType }; + public static Symbol Go_uint = new Symbol() { Name = "uint", Classification = GoClassification.GoBasicType }; + public static Symbol Go_int = new Symbol() { Name = "int", Classification = GoClassification.GoBasicType }; + public static Symbol Go_uintptr = new Symbol() { Name = "uintptr", Classification = GoClassification.GoBasicType }; +} diff --git a/golang/CSharp/SymbolTable.cs b/golang/CSharp/SymbolTable.cs new file mode 100644 index 0000000000..a834fc82e7 --- /dev/null +++ b/golang/CSharp/SymbolTable.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; + +public class SymbolTable { + private Stack scopeStack = new Stack(); + + public SymbolTable() { + var globalScope = new Symbol() { Name = "global", Classification = GoClassification.GoScope }; + scopeStack.Push(globalScope); + } + + public void EnterScope(Symbol newScope) { + var parent = scopeStack.Peek(); + parent.Members[newScope.Name] = newScope; + newScope.Parent = parent; + scopeStack.Push(newScope); + } + + public void ExitScope() { + var current = scopeStack.Peek(); + current.Parent = null; + scopeStack.Pop(); + } + + public Symbol CurrentScope() + { + var current_scope = scopeStack.Peek(); + return current_scope; + } + + public bool Define(Symbol symbol) { + var currentScope = scopeStack.Peek(); + return this.DefineInScope(currentScope, symbol); + } + + public bool DefineInScope(Symbol currentScope, Symbol symbol) { + if (currentScope.Members.ContainsKey(symbol.Name)) { + return false; // Symbol already defined in the current scope + } + symbol.Parent = currentScope; + currentScope.Members[symbol.Name] = symbol; + return true; + } + + public Symbol Resolve(string name) { + foreach (var scope in scopeStack) { + if (scope.Members.TryGetValue(name, out var symbol)) { + return symbol; + } + } + return null; // Symbol not found + } +} diff --git a/golang/CSharp/Table.cs b/golang/CSharp/Table.cs new file mode 100644 index 0000000000..bb4efdc0a8 --- /dev/null +++ b/golang/CSharp/Table.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +public class Table +{ + public List Syms { get; set; } = new List(); + public List Funcs { get; set; } = new List(); + public Dictionary Files { get; set; } = new Dictionary(); + public List Objs { get; set; } = new List(); +// public LineTable Go12Line { get; set; } +} diff --git a/golang/GoParser.g4 b/golang/GoParser.g4 index 4eff485d98..0c574c24e0 100644 --- a/golang/GoParser.g4 +++ b/golang/GoParser.g4 @@ -44,7 +44,7 @@ sourceFile ; packageClause - : PACKAGE packageName {this.myreset();} + : PACKAGE packageName {this.DefinePackageClause();} ; packageName @@ -58,7 +58,7 @@ importDecl ; importSpec - : (DOT | packageName)? importPath {this.addImportSpec();} + : (DOT | packageName)? importPath {this.DefineImportSpec();} ; importPath @@ -101,7 +101,7 @@ aliasDecl ; typeDef - : IDENTIFIER typeParameters? type_ + : IDENTIFIER typeParameters? type_ { this.BindTypeToName(); } ; typeParameters @@ -123,7 +123,15 @@ typeTerm // Function declarations functionDecl - : FUNC IDENTIFIER typeParameters? signature block? + : FUNC IDENTIFIER enterFunctionDecl typeParameters? signature block? exitFunctionDecl + ; + +enterFunctionDecl + : { this.EnterFunctionDecl(); } + ; + +exitFunctionDecl + : { this.ExitFunctionDecl(); } ; methodDecl @@ -143,9 +151,17 @@ varSpec ; block - : L_CURLY statementList R_CURLY + : L_CURLY enterBlock statementList R_CURLY exitScope + ; + +enterBlock + : { this.EnterBlock(); } ; +exitScope + : { this.ExitScope(); } + ; + statementList : ( (SEMI | EOS | /* {this.closingBracket()}? */ ) statement eos)* ; @@ -197,7 +213,7 @@ assign_op ; shortVarDecl - : identifierList DECLARE_ASSIGN expressionList + : identifierList { this.ShortVarDecl(); } DECLARE_ASSIGN expressionList ; labeledStmt @@ -309,9 +325,9 @@ goStmt ; type_ - : typeName typeArgs? - | typeLit - | L_PAREN type_ R_PAREN + : typeName typeArgs? { this.AssignChildToParent(0); } + | typeLit { this.AssignChildToParent(0); } + | L_PAREN type_ R_PAREN { this.AssignChildToParent(1); } ; typeArgs @@ -324,14 +340,14 @@ typeName ; typeLit - : arrayType + : ( arrayType | structType | pointerType | functionType | interfaceType | sliceType | mapType - | channelType + | channelType ) { this.AssignChildToParent(0); } ; arrayType @@ -351,9 +367,17 @@ pointerType ; interfaceType - : INTERFACE L_CURLY ((methodSpec | typeElement) eos)* R_CURLY + : INTERFACE L_CURLY enterInterface ((methodSpec | typeElement) eos)* { this.DefineInterfaceType(); } R_CURLY exitInterface ; +enterInterface + : { this.EnterInterface(); } + ; + +exitInterface + : { this.ExitInterface(); } + ; + sliceType : L_BRACKET R_BRACKET elementType ; @@ -390,7 +414,7 @@ parameters ; parameterDecl - : identifierList? ELLIPSIS? type_ + : identifierList? ELLIPSIS? type_ { this.AddParameterDecl(); } ; expression @@ -493,9 +517,17 @@ element ; structType - : STRUCT L_CURLY (fieldDecl eos)* R_CURLY + : STRUCT L_CURLY enterStruct (fieldDecl eos)* { this.DefineStructType(); } R_CURLY exitStruct ; +enterStruct + : { this.EnterStruct(); } + ; + +exitStruct + : { this.ExitStruct(); } + ; + fieldDecl : (identifierList type_ | embeddedField) tag = string_? ; @@ -526,7 +558,7 @@ typeAssertion ; arguments - : L_PAREN ((expressionList | type_ (COMMA expressionList)?) ELLIPSIS? COMMA?)? R_PAREN + : L_PAREN ((expressionList | { this.IsType() }? type_ (COMMA expressionList)?) ELLIPSIS? COMMA?)? R_PAREN ; methodExpr diff --git a/golang/desc.xml b/golang/desc.xml index a183b954af..9cb7e2fbe9 100644 --- a/golang/desc.xml +++ b/golang/desc.xml @@ -1,5 +1,8 @@ ^4.13.0 + + CSharp