如何在实例化上选择lexer/parser规则
How to choose lexer/parser rule on instanciation
我有一个用于解析各种 SQL 代码的语法。
问题:
- 有时,我希望它处理嵌套评论(例如:Microsoft SQL):
COMMENT: '/*' (COMMENT|.)*? ('*/' | EOF) -> channel(HIDDEN);
- 有时,我希望它不处理它们(例如:Oracle):
COMMENT: '/*' .*? '*/' -> channel(HIDDEN);
我不想:
制作两种不同的语法
编译我的语法两次以获得两个不同的词法分析器和两个不同的解析器。
最好的解决方案是有一个参数,传递给 lexer/parser,以选择使用哪个 "COMMENT implementation"。
我可以这样做吗?如果是,如何,如果不是,我的问题是否有令人满意的解决方案?
谢谢!
您可以在词法分析器中使用语义谓词来实现这一点。您将需要 (1) 将词法分析器和解析器相互分离。 (2) 使用布尔字段 属性 或方法为词法分析器创建基础 class,如果您希望词法分析器允许嵌套注释,则可以将其设置为 true,或设置为 false 以禁止。为了下面的代码,假设您将 "bool nested = false;" 添加到词法分析器基础 class。 (3) 在您的词法分析器语法中,创建一个 COMMENT 规则,如下所示。 (4) 创建词法分析器后,如果要识别嵌套注释,请将 "nested" 字段设置为 true。
COMMENT
: (
{nested}? '/*' (COMMENT|.)*? ('*/' | EOF)
| '/*' .*? '*/') -> channel(HIDDEN)
;
我有一个用于解析各种 SQL 代码的语法。
问题:
- 有时,我希望它处理嵌套评论(例如:Microsoft SQL):
COMMENT: '/*' (COMMENT|.)*? ('*/' | EOF) -> channel(HIDDEN);
- 有时,我希望它不处理它们(例如:Oracle):
COMMENT: '/*' .*? '*/' -> channel(HIDDEN);
我不想:
制作两种不同的语法
编译我的语法两次以获得两个不同的词法分析器和两个不同的解析器。
最好的解决方案是有一个参数,传递给 lexer/parser,以选择使用哪个 "COMMENT implementation"。
我可以这样做吗?如果是,如何,如果不是,我的问题是否有令人满意的解决方案?
谢谢!
您可以在词法分析器中使用语义谓词来实现这一点。您将需要 (1) 将词法分析器和解析器相互分离。 (2) 使用布尔字段 属性 或方法为词法分析器创建基础 class,如果您希望词法分析器允许嵌套注释,则可以将其设置为 true,或设置为 false 以禁止。为了下面的代码,假设您将 "bool nested = false;" 添加到词法分析器基础 class。 (3) 在您的词法分析器语法中,创建一个 COMMENT 规则,如下所示。 (4) 创建词法分析器后,如果要识别嵌套注释,请将 "nested" 字段设置为 true。
COMMENT
: (
{nested}? '/*' (COMMENT|.)*? ('*/' | EOF)
| '/*' .*? '*/') -> channel(HIDDEN)
;