grammars-v4 icon indicating copy to clipboard operation
grammars-v4 copied to clipboard

[golang] Ambiguity in `arguments`.

Open kaby76 opened this issue 7 months ago • 0 comments

Continuing to disambiguate the golang grammar.

In anonymousMethods.go, line 7 has the string fmt.Println(s). The s in the string is ambiguous because s can be parsed two ways:

../examples/anonymousMethods.go.d=109.a=1: (sourceFile (packageClause (PACKAGE "package") (packageName (identifier (IDENTIFIER "samples")))) (eos (EOS "\n\n")) (importDecl (IMPORT "import") (importSpec (importPath (string_ (INTERPRETED_STRING_LIT "\"fmt\""))))) (eos (EOS "\n")) (importDecl (IMPORT "import") (importSpec (DOT ".") (importPath (string_ (INTERPRETED_STRING_LIT "\"time\""))))) (eos (EOS "\n\n")) (functionDecl (FUNC "func") (IDENTIFIER "AnonymousMethods") (signature (parameters (L_PAREN "(") (R_PAREN ")"))) (block (L_CURLY "{") (statementList (statement (simpleStmt (shortVarDecl (identifierList (IDENTIFIER "lambd")) (DECLARE_ASSIGN ":=") (expressionList (expression (primaryExpr (operand (literal (functionLit (FUNC "func") (signature (parameters (L_PAREN "(") (parameterDecl (identifierList (IDENTIFIER "s")) (type_ (typeName (IDENTIFIER "string")))) (R_PAREN ")"))) (block (L_CURLY "{") (statementList (statement (simpleStmt (expressionStmt (expression (primaryExpr (operand (operandName (IDENTIFIER "Sleep"))) (arguments (L_PAREN "(") (expressionList (expression (primaryExpr (operand (literal (basicLit (integer (DECIMAL_LIT "10")))))))) (R_PAREN ")"))))))) (EOS ";") (statement (simpleStmt (expressionStmt (expression (primaryExpr (operand (operandName (IDENTIFIER "fmt"))) (DOT ".") (IDENTIFIER "Println") (arguments (L_PAREN "(") (expressionList (expression (primaryExpr (operand (operandName (IDENTIFIER "s")))))) (R_PAREN ")")))))))) (R_CURLY "}"))))))))))) (EOS "\n") (statement (simpleStmt (expressionStmt (expression (primaryExpr (operand (operandName (IDENTIFIER "lambd"))) (arguments (L_PAREN "(") (expressionList (expression (primaryExpr (operand (literal (basicLit (string_ (INTERPRETED_STRING_LIT "\"From lambda!\"")))))))) (R_PAREN ")"))))))) (EOS "\n") (statement (simpleStmt (expressionStmt (expression (primaryExpr (operand (literal (functionLit (FUNC "func") (signature (parameters (L_PAREN "(") (R_PAREN ")"))) (block (L_CURLY "{") (statementList (statement (simpleStmt (expressionStmt (expression (primaryExpr (operand (operandName (IDENTIFIER "fmt"))) (DOT ".") (IDENTIFIER "Println") (arguments (L_PAREN "(") (expressionList (expression (primaryExpr (operand (literal (basicLit (string_ (INTERPRETED_STRING_LIT "\"Create and invoke!\"")))))))) (R_PAREN ")")))))))) (R_CURLY "}"))))) (arguments (L_PAREN "(") (R_PAREN ")"))))))) (EOS "\n")) (R_CURLY "}"))) (eos (EOS "\n")) (EOF ""))
../examples/anonymousMethods.go.d=109.a=2: (sourceFile (packageClause (PACKAGE "package") (packageName (identifier (IDENTIFIER "samples")))) (eos (EOS "\n\n")) (importDecl (IMPORT "import") (importSpec (importPath (string_ (INTERPRETED_STRING_LIT "\"fmt\""))))) (eos (EOS "\n")) (importDecl (IMPORT "import") (importSpec (DOT ".") (importPath (string_ (INTERPRETED_STRING_LIT "\"time\""))))) (eos (EOS "\n\n")) (functionDecl (FUNC "func") (IDENTIFIER "AnonymousMethods") (signature (parameters (L_PAREN "(") (R_PAREN ")"))) (block (L_CURLY "{") (statementList (statement (simpleStmt (shortVarDecl (identifierList (IDENTIFIER "lambd")) (DECLARE_ASSIGN ":=") (expressionList (expression (primaryExpr (operand (literal (functionLit (FUNC "func") (signature (parameters (L_PAREN "(") (parameterDecl (identifierList (IDENTIFIER "s")) (type_ (typeName (IDENTIFIER "string")))) (R_PAREN ")"))) (block (L_CURLY "{") (statementList (statement (simpleStmt (expressionStmt (expression (primaryExpr (operand (operandName (IDENTIFIER "Sleep"))) (arguments (L_PAREN "(") (expressionList (expression (primaryExpr (operand (literal (basicLit (integer (DECIMAL_LIT "10")))))))) (R_PAREN ")"))))))) (EOS ";") (statement (simpleStmt (expressionStmt (expression (primaryExpr (operand (operandName (IDENTIFIER "fmt"))) (DOT ".") (IDENTIFIER "Println") (arguments (L_PAREN "(") (type_ (typeName (IDENTIFIER "s"))) (R_PAREN ")")))))))) (R_CURLY "}"))))))))))) (EOS "\n") (statement (simpleStmt (expressionStmt (expression (primaryExpr (operand (operandName (IDENTIFIER "lambd"))) (arguments (L_PAREN "(") (expressionList (expression (primaryExpr (operand (literal (basicLit (string_ (INTERPRETED_STRING_LIT "\"From lambda!\"")))))))) (R_PAREN ")"))))))) (EOS "\n") (statement (simpleStmt (expressionStmt (expression (primaryExpr (operand (literal (functionLit (FUNC "func") (signature (parameters (L_PAREN "(") (R_PAREN ")"))) (block (L_CURLY "{") (statementList (statement (simpleStmt (expressionStmt (expression (primaryExpr (operand (operandName (IDENTIFIER "fmt"))) (DOT ".") (IDENTIFIER "Println") (arguments (L_PAREN "(") (expressionList (expression (primaryExpr (operand (literal (basicLit (string_ (INTERPRETED_STRING_LIT "\"Create and invoke!\"")))))))) (R_PAREN ")")))))))) (R_CURLY "}"))))) (arguments (L_PAREN "(") (R_PAREN ")"))))))) (EOS "\n")) (R_CURLY "}"))) (eos (EOS "\n")) (EOF ""))

The problem here is that Antlr cannot distinguish s between expressionList or type_ in arguments. Arguments to a function can be an expression or a type. This rule comes directly from the Spec.

This rule needs predicates to shunt the parse one way or the other. We're going to need to expand on the symbol table. We have to place the predicates in this rule because Antlr "shadows" predicates deeper in the parse: Antlr4 does not backtrack.

kaby76 avatar Apr 13 '25 11:04 kaby76