[英]SQL engine for only SELECT statment - hand written parser in c++
我是编译器的新手,但是我有一个项目SQL引擎-仅用于select语句。 为此,我只需要使用手写的解析器和引擎。 我研究了LL(k)语法和递归下降技术的示例(由stackoverflow建议用于手工编写解析器)。 但是在任何示例中,都没有找到从函数构造解析树的方法。
你们谁能告诉我如何通过仅举“从表中选择columnname1,columnname2”为例逐步完成整个编译过程。 还有一件事-不允许使用Boost库。 数据在内存中。 我使用结构来存储数据。
我会说更简单的方法是像编译器一样处理此问题:
标记化是关于识别“单词”的,对于您的示例,它给出:
"Select", "columnname1", ",", "columnanme2", "from", "table"
解析是将这些令牌列表解释为抽象语法树。 根据您的要求:
我将在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()
),而只是使用不区分大小写的比较 编辑 :
一个不太人为的例子,AST会是什么样子?
"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和2003的BNF语法 。
这些是完整的语法,但是仅分离SELECT分支应该不难。
另外,您可以在http://www.antlr.org/grammar/list上浏览已有的语法。 有一些SQL风格。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.