英文:
How to debug listeners for ANTLR4 target Go
问题
我正在尝试弄清楚为什么我的监听器对规则没有触发,尽管每个规则都被触发,但特定规则没有被触发。我在http://lab.antlr.org/上测试了我的语法。
谢谢。
这段代码会打印输出...
func (f *FSLListener) EnterEveryRule(ctx antlr.ParserRuleContext) {
fmt.Printf("EnterEveryRule %v\n", ctx.GetText())
}
但这段代码不会打印输出
func (f *FSLListener) ExitVar_assignment(ctx *parser.Var_assignmentContext) error {
fmt.Printf("Complete var assignment: %s\n", ctx.GetText())
// ... 更新了这一行以反映我正在处理这个错误,这就是为什么我没有看到任何编译器错误
return nil
}
参考示例监听器https://github.com/antlr/antlr4/blob/master/doc/go-target.md
我的语法是
parser grammar fslParser;
options { tokenVocab=fslLexer; }
r: script* EOF;
script: var_assignment* init_function function_definition*;
var_assignment: VAR VALUE;
init_function: INIT cmd_list RBRACK;
function_definition: VALIDFUNCTIONID cmd_list RBRACK;
cmd_list: (cmd_expression)*;
cmd_expression:
CMD FUNCTIONCALL
| CMD FUNCTIONCALLWITHARGS param_list //function call
| CMD VARREF COMMA param_list // variable reference
| CMD builtin_functions param_list // user-defined function call
;
builtin_functions: (CREATE | DELETE | UPDATE | ADD | SUBTRACT | MULTIPLY | DIVIDE | PRINT);
param_list: ARG param (COMMA ARG param)*;
param:
VARREF
| VALUE
| LETTERS VALUE
| VARPARAM
| VARPARAM VALUE
;
词法分析器
lexer grammar fslLexer;
INIT : 'init: [';
VALIDFUNCTIONID : [a-zA-Z]+ ': [';
VAR : 'var' [0-9]+':';
VALUE : [0-9]+ ('.' [0-9]+)?;
CMD : 'cmd:';
VARREF : '#var'[0-9]+ ;
FUNCTIONCALL : '#' [a-zA-Z]+ ;
FUNCTIONCALLWITHARGS : '#' [a-zA-Z]+',';
VARPARAM : '$' [a-zA-Z]+ ;
DIGITS: [0-9]+;
LETTERS: [a-zA-Z]+;
ARG: LETTERS DIGITS? COLON;
// Define function names as keywords
CREATE : 'create,';
DELETE : 'delete,';
UPDATE : 'update,';
ADD : 'add,';
SUBTRACT: 'subtract,';
MULTIPLY: 'multiply,';
DIVIDE : 'divide,';
PRINT : 'print,';
COLON : ':';
COMMA : ',';
RBRACK : ']';
SPACE : [ \t\r\n]+ -> skip ;
我试图匹配的示例输入:
var1: 1
var2: 2
init: [
cmd: #setup
]
setup: [
cmd: #sum, id: var1, value1: #var1, value2: #var2
cmd: #printAll
]
sum: [
cmd: add, id: $id, operand1: $value1, operand2: $value2
]
printAll: [
cmd: print, value: #var1
cmd: print, value: #var2
cmd: print, value: #var3
]
英文:
I'm trying to figure out why my listeners aren't triggering for the rules when every rule is being triggered but not the specific rules. I tested my grammar works on http://lab.antlr.org/
Thank you.
this prints...
func (f *FSLListener) EnterEveryRule(ctx antlr.ParserRuleContext) {
fmt.Printf("EnterEveryRule %v\n", ctx.GetText())
}
but this doesn't
func (f *FSLListener) ExitVar_assignment(ctx *parser.Var_assignmentContext) error {
fmt.Printf("Complete var assignment: %s\n", ctx.GetText())
// ... updated this line to reflect that I was handling this error which is why I didn't see any compiler errors
return nil
}
Following the example listener in https://github.com/antlr/antlr4/blob/master/doc/go-target.md
My Grammar is
parser grammar fslParser;
options { tokenVocab=fslLexer; }
r: script* EOF;
script: var_assignment* init_function function_definition*;
var_assignment: VAR VALUE;
init_function: INIT cmd_list RBRACK;
function_definition: VALIDFUNCTIONID cmd_list RBRACK;
cmd_list: (cmd_expression)*;
cmd_expression:
CMD FUNCTIONCALL
| CMD FUNCTIONCALLWITHARGS param_list //function call
| CMD VARREF COMMA param_list // variable reference
| CMD builtin_functions param_list // user-defined function call
;
builtin_functions: (CREATE | DELETE | UPDATE | ADD | SUBTRACT | MULTIPLY | DIVIDE | PRINT);
param_list: ARG param (COMMA ARG param)*;
param:
VARREF
| VALUE
| LETTERS VALUE
| VARPARAM
| VARPARAM VALUE
;
Lexer
lexer grammar fslLexer;
INIT : 'init: [' ;
VALIDFUNCTIONID : [a-zA-Z]+ ': [';
VAR : 'var' [0-9]+':' ;
VALUE : [0-9]+ ('.' [0-9]+)? ;
CMD : 'cmd:' ;
VARREF : '#var'[0-9]+ ;
FUNCTIONCALL : '#' [a-zA-Z]+ ;
FUNCTIONCALLWITHARGS : '#' [a-zA-Z]+',' ;
VARPARAM : '$' [a-zA-Z]+ ;
DIGITS: [0-9]+;
LETTERS: [a-zA-Z]+;
ARG: LETTERS DIGITS? COLON;
// Define function names as keywords
CREATE : 'create,' ;
DELETE : 'delete,' ;
UPDATE : 'update,' ;
ADD : 'add,' ;
SUBTRACT: 'subtract,' ;
MULTIPLY: 'multiply,' ;
DIVIDE : 'divide,' ;
PRINT : 'print,' ;
COLON : ':';
COMMA : ',';
RBRACK : ']';
SPACE : [ \t\r\n]+ -> skip ;
Example input I'm trying to match:
var1: 1
var2: 2
init: [
cmd: #setup
]
setup: [
cmd: #sum, id: var1, value1: #var1, value2: #var2
cmd: #printAll
]
sum: [
cmd: add, id: $id, operand1: $value1, operand2: $value2
]
printAll: [
cmd: print, value: #var1
cmd: print, value: #var2
cmd: print, value: #var3
]
答案1
得分: 2
func (f *FSLListener) ExitVar_assignment(ctx *parser.Var_assignmentContext) {
fmt.Printf("完成变量赋值:%s\n", ctx.GetText())
}
应该是这样的:
func (f *FSLListener) ExitVar_assignment(ctx *parser.Var_assignmentContext) {
fmt.Printf("完成变量赋值:%s\n", ctx.GetText())
}
这是Go代码中的一个简单语法错误。实现没有返回值。应用此更改后,我可以看到以下输出:
完成变量赋值:var1:1
完成变量赋值:var2:2
请注意,生成的fslParserListener
接口是:
// fslParserListener是由fslParser生成的解析树的完整监听器。
type fslParserListener interface {
// ExitVar_assignment在退出var_assignment产生式时调用。
ExitVar_assignment(c *Var_assignmentContext)
// 其他代码已省略
}
它没有返回值。
为了强制接口的一致性,您可以导出监听器接口,并将以下语句添加到您的代码中(假设接口导出为parser.FslParserListener
):
var _ parser.FslParserListener = (*FSLListener)(nil)
英文:
func (f *FSLListener) ExitVar_assignment(ctx *parser.Var_assignmentContext) error {
fmt.Printf("Complete var assignment: %s\n", ctx.GetText())
}
Should be:
func (f *FSLListener) ExitVar_assignment(ctx *parser.Var_assignmentContext) {
fmt.Printf("Complete var assignment: %s\n", ctx.GetText())
}
This is a simple syntax error in the Go code. The implementation does not have a return value. After applying this change, I can see this output:
Complete var assignment: var1:1
Complete var assignment: var2:2
And please note that the generated fslParserListener
interface is:
// fslParserListener is a complete listener for a parse tree produced by fslParser.
type fslParserListener interface {
// ExitVar_assignment is called when exiting the var_assignment production.
ExitVar_assignment(c *Var_assignmentContext)
// Other codes truncated
}
It does not have a return value.
To force the interface compliance, you can export the listener interface and add this statement to your code (it assumes that the interface is exported as parser.FslParserListener
):
var _ parser.FslParserListener = (*FSLListener)(nil)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论