应该在哪里检查类型,在 ANTLR 语法中还是在访问者中?
Where types should be checked, in ANTLR grammar or in the visitor?
我在 ANTRL 中的语法的一部分是布尔表达式。目前,expr 仅适用于字符串。
bool_expr
: '(' bool_expr ')' #boolParenOp
| left=expr oper=OP right=expr #boolOp
| TRUE #boolAtom
| FALSE #boolAtom
;
expr
: attributeAccess
| STRING
;
如果我想将整数或数字添加到 bool_expr,我是否应该检查语法中的类型,添加更多规则,例如“left =num_expr oper=OP right=num_expr" 或者查看访问者中"expr"的内容 ?
语法中的编码类型¹ 扩展性不佳。你添加的类型越多,你需要的语法规则就越多,一旦你拥有超过固定数量的内置类型(比如你允许元组类型甚至用户可定义的类型),它就变得不可能了。
即使没有它,也有很多机会 运行 解决问题。例如,假设您向语言添加了变量和函数(或任何其他可能的功能)。变量和函数调用是 bool_expr
s 还是 int_expr
s 或两者?除非您只想将变量和函数限制为一种类型,否则两者都需要。函数参数相同。但是现在你的语法有歧义。假设您有 f(x)
作为表达式。不可能仅从该表达式知道 x
是 bool_expr
还是 int_expr
- 您必须知道 x
是如何定义的(这需要上下文敏感性).
因此,只有一个表达式规则可以匹配语法中所有类型的表达式,并作为一个单独的步骤对树执行类型检查,这样会更加稳健。
¹ 也就是说,以这样一种方式构建语法,您可以通过了解它匹配的产生式来了解表达式的类型,并且所有生成的表达式在构造上都是类型正确的。
我在 ANTRL 中的语法的一部分是布尔表达式。目前,expr 仅适用于字符串。
bool_expr
: '(' bool_expr ')' #boolParenOp
| left=expr oper=OP right=expr #boolOp
| TRUE #boolAtom
| FALSE #boolAtom
;
expr
: attributeAccess
| STRING
;
如果我想将整数或数字添加到 bool_expr,我是否应该检查语法中的类型,添加更多规则,例如“left =num_expr oper=OP right=num_expr" 或者查看访问者中"expr"的内容 ?
语法中的编码类型¹ 扩展性不佳。你添加的类型越多,你需要的语法规则就越多,一旦你拥有超过固定数量的内置类型(比如你允许元组类型甚至用户可定义的类型),它就变得不可能了。
即使没有它,也有很多机会 运行 解决问题。例如,假设您向语言添加了变量和函数(或任何其他可能的功能)。变量和函数调用是 bool_expr
s 还是 int_expr
s 或两者?除非您只想将变量和函数限制为一种类型,否则两者都需要。函数参数相同。但是现在你的语法有歧义。假设您有 f(x)
作为表达式。不可能仅从该表达式知道 x
是 bool_expr
还是 int_expr
- 您必须知道 x
是如何定义的(这需要上下文敏感性).
因此,只有一个表达式规则可以匹配语法中所有类型的表达式,并作为一个单独的步骤对树执行类型检查,这样会更加稳健。
¹ 也就是说,以这样一种方式构建语法,您可以通过了解它匹配的产生式来了解表达式的类型,并且所有生成的表达式在构造上都是类型正确的。