4

我正在使用 ANTLR 3 执行以下操作。

假设我有一个 SQL 查询。我知道一般来说它是 WHERE、ORDER BY 和 GROUP BY 子句是可选的。就 ANTLR 的语法而言,我会这样描述:

查询:select_clause from_clause where_clause?group_by_clause?order_by_clause?

每个子句的规则显然将从各自的关键字开始。

我真正需要的是在不处理其内部结构的情况下将每个子句的内容提取为字符串。

为此,我从以下语法开始:

询问 :
    select_clause from_clause where_clause? group_by_clause?order_by_clause?
EOF;

选择子句:
    SELECT_CLAUSE
;

from_clause :
    FROM_CLAUSE
;

where_clause :
    WHERE_CLAUSE
;

group_by_clause:
    GROUP_BY_CLAUSE
;

order_by_clause :
    ORDER_BY_CLAUSE
;

SELECT_CLAUSE : '选择' ANY_CHAR*;

FROM_CLAUSE : '来自' ANY_CHAR*;

WHERE_CLAUSE : '在哪里' ANY_CHAR*;

GROUP_BY_CLAUSE : '分组' ANY_CHAR*;

ORDER_BY_CLAUSE : 'order by' ANY_CHAR*;

ANY_CHAR : .;

WS:''+ {skip();};

这个没用。我进一步尝试编写正确的语法,但没有成功。我怀疑这个任务对 ANTLR3 是可行的,但我只是想念 smth。

更一般地说,我希望能够将输入流中的字符收集到单个标记中,直到遇到一个表示新标记开始的特定关键字。这个关键字应该是新令牌的一部分。

你能帮我吗?

4

1 回答 1

2

为什么不将它们添加到您的令牌中,而不是将它们移到ANY_CHAR*解析器规则中呢?您甚至可以使用重写规则将这些单个标记“粘合”在一起。

快速演示:

grammar T;

options { output=AST; }
tokens  { QUERY; ANY; }

query           : select_clause from_clause where_clause? group_by_clause? order_by_clause? EOF
                  -> ^(QUERY select_clause from_clause where_clause? group_by_clause? order_by_clause?)
                ;
select_clause   : SELECT_CLAUSE^ any;
from_clause     : FROM_CLAUSE^ any;
where_clause    : WHERE_CLAUSE^ any;
group_by_clause : GROUP_BY_CLAUSE^ any;
order_by_clause : ORDER_BY_CLAUSE^ any;
any             : ANY_CHAR* -> ANY[$text];

SELECT_CLAUSE   : 'select';
FROM_CLAUSE     : 'from';
WHERE_CLAUSE    : 'where';
GROUP_BY_CLAUSE : 'group' S+ 'by';
ORDER_BY_CLAUSE : 'order' S+ 'by';
ANY_CHAR        : . ;
WS              : S+ {skip();};

fragment S      : ' ' | '\t' | '\r' | '\n';

如果您现在解析输入:

从您的地下室订单中选择任何东西

将创建以下 AST:

在此处输入图像描述

尝试在你的词法分析器中做类似的事情会很麻烦,并且意味着一些自定义代码(或谓词)来检查字符流中的关键字(两者都不漂亮!)。

于 2013-02-12T22:23:23.420 回答