SQL 是上下文无关语言还是其他类型的语言?
4 回答
根据https://stackoverflow.com/a/31265136 SQL 不是常规语言。简短的解释是每个选择查询看起来像
SELECT x FROM y WHERE z
并且y
可以是另一个选择查询本身,因此不能用有限状态机模拟。如前所述,Backus-Naur 形式中有一些 SQL 标准的 CFG ,因此 SQL 是非常规上下文无关语言。
@aquinas 写道:
你的意思是SQL也有规律吗?CFG 包含常规语言。所以,它们并不是相互排斥的。不过,要回答您的问题,SQL 不是常规语言。
@MSX 写道:
澄清一下,当一种语言由上下文无关语法生成时,它就是上下文无关的。网上有 SQL 上下文无关的语法定义。只是谷歌周围,你会找到一些。例如,这里有一个。
任何 SQL 的 CFG 都可以完成大部分工作,但总是有点过于宽松。
SQL CFG 的一个很好的例子来自 antlr:https ://github.com/antlr/grammars-v4/blob/master/sql/plsql/PlSqlParser.g4#L1982
但是在该行 (1982),您会看到在 a 中values_clause
,列值被递归添加,而不管可能指定了多少列,或者另一行中有多少值,这是无效的 sql:
insert into xyz values
(1, 'hello'),
(2, 'bye'),
(3, 'hi', 'uhm...'); -- invalid!
尝试在这里运行它:https ://www.db-fiddle.com/f/6gwgcg6qBLKpFbCEPtB6dy/0
这种语法永远不能被 CFG 完全封装,因为它等同于{ (a^n)(b^n)(c^n) : n ≥ 1 }
语言,众所周知,CFG 中不允许(但 CSG中允许)
您可能会争辩说这是运行时错误而不是解析错误。但是你可以对每一种被解释的语言使用相同的参数,所以它有点灰色地带。
PL/SQL 上下文中的相似之处可以是 SQL 或 PL/SQL 究竟是什么代码,因为如果我们将函数关键字定义为具体的,那么如果我们要控制可以使用哪些函数,则必须知道该上下文