Skip to content

Commit c2909fc

Browse files
authored
[golang] Fixes for #4460 and #4462 (ambiguities) (#4461)
* Fix for #4460: disambiguating primaryExpr. * Correct isMethodExpr() for parsing the "fmt" package. With the fixes, parse time for the "fmt" package is more than twice as fast as before all these ambiguity fixes. * Fixes for #4462. * Add Antlr4ng port. * Add TypeScript port. * Fix TypeScript. * Add Cpp port and update other ports accordingly. * Update to bypass Cpp build problem. Antlr4 has a blocking bug, and the fix is not being merged. * Add Dart port. * Update ports with symbol table info, reset. * Add Java port. * Add Python3 port. * Fix indentation for Python3 port.
1 parent a56ac88 commit c2909fc

File tree

11 files changed

+835
-90
lines changed

11 files changed

+835
-90
lines changed

_scripts/templates/Cpp/cmake/st.ExternalAntlr4Cpp.cmake

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ include(ExternalProject)
55
#set(ANTLR4_ROOT ${CMAKE_CURRENT_BINARY_DIR}/antlr4_runtime/src/antlr4_runtime)
66
set(ANTLR4_ROOT <temp_dir>/antlr4_runtime/src/antlr4_runtime)
77
set(ANTLR4_INCLUDE_DIRS ${ANTLR4_ROOT}/runtime/Cpp/runtime/src)
8-
set(ANTLR4_GIT_REPOSITORY https://github.com/antlr/antlr4.git)
8+
set(ANTLR4_GIT_REPOSITORY https://github.com/kaby76/antlr4.git)
99
if(NOT DEFINED ANTLR4_TAG)
1010
# Set to branch name to keep library updated at the cost of needing to rebuild after 'clean'
1111
# Set to commit hash to keep the build stable and does not need to rebuild after 'clean'
@@ -96,7 +96,7 @@ else()
9696
antlr4_runtime
9797
PREFIX <temp_dir>/antlr4_runtime
9898
GIT_REPOSITORY ${ANTLR4_GIT_REPOSITORY}
99-
GIT_TAG df4d68c09cdef73e023b8838a8bc7ca4dff1d1de # ${ANTLR4_TAG}
99+
GIT_TAG f5bd4bec221ca5d916839eca52759720fa28d24c # df4d68c09cdef73e023b8838a8bc7ca4dff1d1de # ${ANTLR4_TAG}
100100
DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}
101101
BUILD_COMMAND ""
102102
BUILD_IN_SOURCE 1

golang/Antlr4ng/GoParserBase.ts

+107-7
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,126 @@
11
import { Parser, TokenStream, BufferedTokenStream, Token } from 'antlr4ng';
22
import { GoLexer } from './GoLexer.js';
3+
import { GoParser, ImportSpecContext } from './GoParser.js';
34

45
export default abstract class GoParserBase extends Parser {
6+
7+
debug: boolean;
8+
table: Set<string>;
9+
510
constructor(input: TokenStream) {
611
super(input);
712
}
813

14+
protected myreset(): void {
15+
this.debug = false;
16+
this.table = new Set<string>();
17+
}
18+
919
protected closingBracket(): boolean {
1020
const stream = this.inputStream as BufferedTokenStream;
11-
const la = stream.LA(1);
12-
return la === GoLexer.R_CURLY || la === GoLexer.R_PAREN || la === Token.EOF;
21+
const la = stream.LT(1);
22+
return la.type === GoParser.R_CURLY || la.type === GoParser.R_PAREN || la.type === Token.EOF;
23+
}
24+
25+
public isNotReceive(): boolean
26+
{
27+
const stream = this.inputStream as BufferedTokenStream;
28+
const la = stream.LT(2);
29+
return la.type !== GoParser.RECEIVE;
30+
}
31+
32+
public addImportSpec(): void
33+
{
34+
const ctx = this.context;
35+
const count = ctx.getChildCount();
36+
if (!(ctx instanceof ImportSpecContext)) {
37+
return;
38+
}
39+
const importSpec = ctx;
40+
var packageName = importSpec.packageName();
41+
if (packageName != null)
42+
{
43+
var name = packageName.getText();
44+
if (this.debug) console.log("Entering " + name);
45+
this.table.add(name);
46+
}
47+
else
48+
{
49+
var name = importSpec.importPath().getText();
50+
name = name.replaceAll("\"", "");
51+
name = name.replaceAll("\\", "/");
52+
const pathArr = name.split('/');
53+
const fileArr = pathArr.at(-1).split('.');
54+
const fileName = fileArr.at(-1).toString();
55+
if (this.debug) console.log("Entering " + fileName);
56+
this.table.add(fileName);
57+
}
1358
}
1459

1560
protected isType(): boolean {
1661
const stream = this.inputStream as BufferedTokenStream;
1762
const la = stream.LA(1);
18-
return la !== GoLexer.IDENTIFIER;
63+
return la !== GoParser.IDENTIFIER;
64+
}
65+
66+
public isOperand(): boolean
67+
{
68+
const stream = this.inputStream as BufferedTokenStream;
69+
const la = stream.LT(1);
70+
if (la.text === "err") return true;
71+
var result = true;
72+
if (la.type !== GoParser.IDENTIFIER) {
73+
if (this.debug) console.log("isOperand Returning " + result + " for " + la);
74+
return result;
75+
}
76+
result = this.table.has(la.text);
77+
var la2 = stream.LT(2);
78+
// If it's not followed by a '.', then it really should be
79+
// considered as operand.
80+
if (la2.type !== GoParser.DOT) {
81+
result = true;
82+
if (this.debug) console.log("isOperand Returning " + result + " for " + la);
83+
return result;
84+
}
85+
// If it's followed by '.', and then followed by '(', then
86+
// it is a typeAssertion, and so la must be an operand.
87+
var la3 = stream.LT(3);
88+
if (la3.type === GoParser.L_PAREN)
89+
{
90+
result = true;
91+
if (this.debug) console.log("isOperand Returning " + result + " for " + la);
92+
return result;
93+
}
94+
if (this.debug) console.log("isOperand Returning " + result + " for " + la);
95+
return result;
1996
}
2097

21-
protected isNotReceive(): boolean {
98+
public isConversion(): boolean
99+
{
22100
const stream = this.inputStream as BufferedTokenStream;
23-
const la = stream.LA(2);
24-
return la !== GoLexer.RECEIVE;
25-
}
101+
const la = stream.LT(1);
102+
var result = la.type !== GoParser.IDENTIFIER;
103+
if (this.debug) console.log("isConversion Returning " + result + " for " + la);
104+
return result;
105+
}
106+
107+
public isMethodExpr(): boolean
108+
{
109+
const stream = this.inputStream as BufferedTokenStream;
110+
const la = stream.LT(1);
111+
var result = true;
112+
// See if it looks like a method expr.
113+
if (la.type === GoParser.STAR) {
114+
if (this.debug) console.log("isMethodExpr Returning " + result + " for " + la);
115+
return result;
116+
}
117+
if (la.type !== GoParser.IDENTIFIER) {
118+
result = false;
119+
if (this.debug) console.log("isMethodExpr Returning " + result + " for " + la);
120+
return result;
121+
}
122+
result = ! this.table.has(la.text);
123+
if (this.debug) console.log("isMethodExpr Returning " + result + " for " + la);
124+
return result;
125+
}
26126
}

golang/CSharp/GoParserBase.cs

+97-11
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
using System;
22
using System.Collections.Generic;
33
using System.IO;
4+
using System.Linq;
45
using Antlr4.Runtime;
56

67
public abstract class GoParserBase : Parser
78
{
9+
const bool debug = false;
10+
HashSet<string> table = new HashSet<string>();
11+
812
protected GoParserBase(ITokenStream input)
913
: base(input)
1014
{
@@ -15,30 +19,112 @@ protected GoParserBase(ITokenStream input, TextWriter output, TextWriter errorOu
1519
{
1620
}
1721

22+
private ITokenStream tokenStream
23+
{
24+
get
25+
{
26+
return TokenStream;
27+
}
28+
}
29+
30+
protected void myreset()
31+
{
32+
table = new HashSet<string>();
33+
}
1834

1935
protected bool closingBracket()
2036
{
21-
int la = tokenStream.LA(1);
22-
return la == GoLexer.R_PAREN || la == GoLexer.R_CURLY || la == Eof;
37+
var la = tokenStream.LT(1);
38+
return la.Type == GoParser.R_PAREN || la.Type == GoParser.R_CURLY || la.Type == Eof;
2339
}
2440

25-
private ITokenStream tokenStream
41+
public bool isNotReceive()
2642
{
27-
get
43+
var la = tokenStream.LT(2);
44+
return la.Type != GoParser.RECEIVE;
45+
}
46+
47+
public void addImportSpec()
48+
{
49+
var ctx = this.Context;
50+
var count = ctx.ChildCount;
51+
var importSpec = ctx as GoParser.ImportSpecContext;
52+
if (importSpec == null) return;
53+
var packageName = importSpec.packageName();
54+
if (packageName != null)
2855
{
29-
return TokenStream;
56+
var name = packageName.GetText();
57+
if (debug) System.Console.WriteLine("Entering " + name);
58+
table.Add(name);
59+
}
60+
else
61+
{
62+
var name = importSpec.importPath().GetText();
63+
name = name.Replace("\"", "");
64+
name = name.Replace("\\", "/");
65+
string[] pathArr = name.Split('/');
66+
string[] fileArr = pathArr.Last().Split('.');
67+
string fileName = fileArr.Last().ToString();
68+
if (debug) System.Console.WriteLine("Entering " + fileName);
69+
table.Add(fileName);
3070
}
3171
}
3272

33-
public bool isType()
73+
public bool isOperand()
3474
{
35-
int la = tokenStream.LA(1);
36-
return la != GoLexer.IDENTIFIER;
75+
var la = tokenStream.LT(1);
76+
if (la.Text == "err") return true;
77+
bool result = true;
78+
if (la.Type != GoParser.IDENTIFIER) {
79+
if (debug) System.Console.WriteLine("isOperand Returning " + result + " for " + la);
80+
return result;
81+
}
82+
result = table.Contains(la.Text);
83+
var la2 = tokenStream.LT(2);
84+
// If it's not followed by a '.', then it really should be
85+
// considered as operand.
86+
if (la2.Type != GoParser.DOT) {
87+
result = true;
88+
if (debug) System.Console.WriteLine("isOperand Returning " + result + " for " + la);
89+
return result;
90+
}
91+
// If it's followed by '.', and then followed by '(', then
92+
// it is a typeAssertion, and so la must be an operand.
93+
var la3 = tokenStream.LT(3);
94+
if (la3.Type == GoParser.L_PAREN)
95+
{
96+
result = true;
97+
if (debug) System.Console.WriteLine("isOperand Returning " + result + " for " + la);
98+
return result;
99+
}
100+
if (debug) System.Console.WriteLine("isOperand Returning " + result + " for " + la);
101+
return result;
37102
}
38103

39-
public bool isNotReceive()
104+
public bool isConversion()
40105
{
41-
int la = tokenStream.LA(2);
42-
return la != GoLexer.RECEIVE;
106+
var la = tokenStream.LT(1);
107+
var result = la.Type != GoParser.IDENTIFIER;
108+
if (debug) System.Console.WriteLine("isConversion Returning " + result + " for " + la);
109+
return result;
110+
}
111+
112+
public bool isMethodExpr()
113+
{
114+
var la = tokenStream.LT(1);
115+
bool result = true;
116+
// See if it looks like a method expr.
117+
if (la.Type == GoParser.STAR) {
118+
if (debug) System.Console.WriteLine("isMethodExpr Returning " + result + " for " + la);
119+
return result;
120+
}
121+
if (la.Type != GoParser.IDENTIFIER) {
122+
result = false;
123+
if (debug) System.Console.WriteLine("isMethodExpr Returning " + result + " for " + la);
124+
return result;
125+
}
126+
result = ! table.Contains(la.Text);
127+
if (debug) System.Console.WriteLine("isMethodExpr Returning " + result + " for " + la);
128+
return result;
43129
}
44130
}

0 commit comments

Comments
 (0)