繁体   English   中英

仅用于SELECT语句的SQL引擎-C ++中的手写解析器

[英]SQL engine for only SELECT statment - hand written parser in c++

我是编译器的新手,但是我有一个项目SQL引擎-仅用于select语句。 为此,我只需要使用手写的解析器和引擎。 我研究了LL(k)语法和递归下降技术的示例(由stackoverflow建议用于手工编写解析器)。 但是在任何示例中,都没有找到从函数构造解析树的方法。
你们谁能告诉我如何通过仅举“从表中选择columnname1,columnname2”为例逐步完成整个编译过程。 还有一件事-不允许使用Boost库。 数据在内存中。 我使用结构来存储数据。

我会说更简单的方法是像编译器一样处理此问题:

  • 代币化
  • 解析(创建AST)

标记化是关于识别“单词”的,对于您的示例,它给出:

"Select", "columnname1", ",", "columnanme2", "from", "table"

解析是将这些令牌列表解释为抽象语法树。 根据您的要求:

  • 第一个令牌应为“选择”(不区分大小写)
  • 后面可能跟有“ *”或以逗号分隔的列名列表
  • “ from”(不区分大小写)标记列表的结尾
  • 表名后跟

我将在Python中对此进行概述

class Select:
  def __init__(self):
    self.columnList = None
    self.tableName = None

def Tokenize(statement):
  result = []
  for word in statement.split(" "):
    sub = word.split(",")             # the comma may not be separated by space
    for i in range(len(sub)-1):
      result.append(sub[i].lower())   # case insensitive
      result.append(",")
    result.append(sub[-1])
  return result

def CreateSelect(tokens):
  if len(tokens) == 0: raise NoToken()
  if tokens[0] != "select": raise NotASelectStatement()

  select = Select()

  i = 1
  while tokens[i] != "from":
    if tokens[i] == "*":
      select.columnList == ALL
      break
    else:
      select.columnList.append(tokens[i])
      i = i + 1
      if tokens[i] != ",": raise ExpectedComma(i)
      i = i + 1

   select.tableName = tokens[i+1]

当然,如您所知,这是一个有限的示例:

  • 它不考虑多个表
  • 它不考虑混叠
  • 它不考虑嵌套的选择语句

但是它工作得很好并且非常有效。 通常,如果我们将标记化和解析阶段结合起来,它可能会更加高效,但是我发现一般来说,它只会使代码更难阅读。

还要注意,对于正确的错误报告,这样做会更好:

  • 不要更改标记( .lower() ),而只是使用不区分大小写的比较
  • 将适当的源位置附加到每个令牌(行/列),以便能够将用户指向正确的位置

编辑

一个不太人为的例子,A​​ST会是什么样子?

"select foo, bar from FooBar where category = 'example' and id < 500;"

我们走吧:

Select
|_ Columns (foo, bar)
|_ Table (FooBar)
\_ Where
   \_ And
      |_ Equal (category, 'example')
      \_ LessThan (id, 500)

在这里,您有一个想要生成的树状结构。

您可能还可以在线找到SQL 92、99和2003BNF语法

这些是完整的语法,但是仅分离SELECT分支应该不难。

另外,您可以在http://www.antlr.org/grammar/list上浏览已有的语法。 有一些SQL风格。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM