ANTLR3:匹配所有内容直到特定关键字

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

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

query : select_clause from_clause where_clause? group_by_clause? order_by_clause?

每个子句的规则显然都以相应的关键字开头.

我真正需要的是将每个子句的内容提取为字符串而不处理其内部结构.

为此,我开始使用以下语法:

query :
    select_clause from_clause where_clause? group_by_clause? order_by_clause?
EOF;

select_clause :
    SELECT_CLAUSE
;

from_clause :
    FROM_CLAUSE
;

where_clause :
    WHERE_CLAUSE
;

group_by_clause :
    GROUP_BY_CLAUSE
;

order_by_clause :
    ORDER_BY_CLAUSE
;

SELECT_CLAUSE : 'select' ANY_CHAR*;

FROM_CLAUSE : 'from' ANY_CHAR*;

WHERE_CLAUSE : 'where' ANY_CHAR*;

GROUP_BY_CLAUSE : 'group by' ANY_CHAR*;

ORDER_BY_CLAUSE : 'order by' ANY_CHAR*;

ANY_CHAR : .;

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

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

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

你能帮我吗?

最佳答案 不是将它们添加到令牌中,为什么不将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';

如果你现在解析输入:

select JUST ABOUT ANYTHING from YOUR BASEMENT order by WHATEVER

将创建以下AST:

尝试在你的词法分析器中做类似的事情会很混乱,并且意味着一些自定义代码(或谓词)在char-stream中检查关键字(两者都不漂亮!).

点赞