【发布时间】:2020-01-09 02:57:41
【问题描述】:
我正在寻找一个简单问题的解决方案。
示例:
SELECT date, date(date)
FROM date;
这是一个相当愚蠢的示例,其中一个表、它的列和一个函数都具有名称“日期”。
我的语法的sn-p(非常简化):
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'
;
DATE 是一个关键字(它在语法的其他地方使用)。 如果我希望它被我的语法识别为普通单词,这是我的解决方案:
1) 我将它添加到我使用 REGULAR_WORD 的所有地方,就在它旁边。 示例:
selected_element
: function
| REGULAR_WORD
| DATE
;
=> 我不想要这个解决方案。我不仅将“DATE”作为关键字,而且我有许多使用 REGULAR_WORD 的规则,因此我需要将许多 (50+) 关键字的列表添加到许多 (20+) 解析器规则中:绝对丑陋。
优点:制作一棵干净的树
缺点:弄脏语法
2) 我在两者之间使用解析器规则来获取所有这些关键字,然后用该解析器规则替换每次出现的 REGULAR_WORD。 示例:
word
: REGULAR_WORD
| DATE
;
selected_element
: function
| word
;
=> 我也不想要这个解决方案,因为它在树中添加了一个解析器规则并污染了信息(我不想知道“日期”是一个词,我想知道它是一个 selected_element 、函数、function_argument 或 from_element ...
优点:语法清晰
缺点:弄脏树
无论哪种方式,我都有一棵脏树或脏语法。没有办法让两者都干净吗?
我寻找别名,解析器片段等效,但似乎 ANTLR4 没有任何?
谢谢你,祝你有美好的一天!
【问题讨论】:
-
恐怕这个问题没有解决办法。它被称为“上下文敏感词法分析器”。当您想要向后兼容的语法时,这是您必须付出的代价(例如 Oracle SQL - 它们确实区分“关键字”和“保留词”)
-
@ibre5041:谢谢你的回答。这就是我所害怕的。但是,“它被称为“上下文敏感词法分析器””是什么意思?你的意思是解决我的问题的语法会有一个“上下文敏感词法分析器”吗?