当前位置: 首页 > 知识库问答 >
问题:

ANTLR4:清除语法和关键字树(别名?)

宰父存
2023-03-14
SELECT date, date(date)
FROM date;
simple_select
    : SELECT selected_element (',' selected_element) FROM from_element ';'
    ;

selected_element
    : function
    | REGULAR_WORD
    ;

function
    : REGULAR_WORD '(' function_argument ')'
    ;

function_argument
    : REGULAR_WORD
    ;

from_element
    : REGULAR_WORD
    ;


DATE:     D A T E;
FROM:     F R O M;
SELECT:   S E L E C T;

REGULAR_WORD
    : (SIMPLE_LETTER) (SIMPLE_LETTER | '0'..'9')*
    ;

fragment SIMPLE_LETTER
    : 'a'..'z'
    | 'A'..'Z'
    ;
selected_element
    : function
    | REGULAR_WORD
    | DATE
    ;

=>我不想要这种解决方案。我不是只有“DATE”作为关键字,而且我有许多使用REGULAR_WORD的规则,所以我需要在许多(20+)解析器规则中添加许多(50+)关键字,如DATE:这绝对是丑陋的。

优点:做一棵干净的树

缺点:制造肮脏的语法

word
    : REGULAR_WORD
    | DATE
    ;

selected_element
    : function
    | word
    ;

共有1个答案

祁烨
2023-03-14

Antlr4语法库中有四种不同的SQL方言语法,这四种语法都使用第二种策略。因此,在Antlr4 sql语法编写者中似乎有一个共识。鉴于Antlr4 LEXER的设计,我不相信有更好的解决方案。

正如您所说,这会在完整的解析树中产生一些噪音,但是相关的非终端(函数selected_element等)肯定存在,在我看来,将单元产品折叠出解析树并不困难。

据我所知,在设计Antlr4时,决定只自动生成完整的解析树,因为压缩(“抽象”)语法树的设计太特殊了,不适合语法DSL。因此,如果您发现AST更方便,您有责任自己生成一个AST。这通常是直截了当的,尽管它涉及许多样板。

 类似资料:
  • if else for do while switch case loop unitl break continue goto return 以上为基本的逻辑语句。 try catch finally throw 以上为基本的错误处理语句。 void int string short byte long float double char bool object 以上为内置的数据类型。 var 用

  • 我在ANTLR4中有以下语法 一切都很好.我在语法1中哪里错了?

  • 用户按下隐藏键盘按钮或后退按钮。因此,当用户隐藏键盘时,我需要清除对搜索视图的关注。 我试过这个,但它不工作。当用户隐藏键盘时,焦点仍然存在。 这是:

  • 通过前面的学习我们了解到切片其实就是多个相同类型元素的连续集合,既然切片是一个集合,那么我们就可以迭代其中的元素,Go语言有个特殊的关键字 range,它可以配合关键字 for 来迭代切片里的每一个元素,如下所示: 第 4 行中的 index 和 value 分别用来接收 range 关键字返回的切片中每个元素的索引和值,这里的 index 和 value 不是固定的,读者也可以定义成其它的名字。