仓库源文站点原文

前文 语法分析成功后,挺方便能从如下中文语句:

创建读者表,编号为整数,邮箱为不重复不为空的文本,出生年为整数。删除读者表。

生成对应SQL语句:

CREATE TABLE 读者 ( 编号 INTEGER, 邮箱 TEXT UNIQUE NOT NULL, 出生年 INTEGER ); DROP TABLE 读者;

相关python代码片段如下:

@分析器母机.语法规则("代码 : 各句 句号")
def 代码(片段):
    return f"{片段[0]};"

@分析器母机.语法规则("各句 : 句 | 各句 句号 句")
def 各句(片段):
    return f"{片段[0]}" if len(片段) == 1 else f"{片段[0]}; {片段[2]}"

@分析器母机.语法规则("句 : 删表 | 建表")
def 句(片段):
    return 片段[0]

@分析器母机.语法规则("删表 : 删除 标识符 表")
def 删表声明(片段):
    return f"DROP TABLE {片段[1].getstr()}"

@分析器母机.语法规则("建表 : 表声明 逗号 各列声明")
def 建表(片段):
    return f"{片段[0]} ( {片段[2]} )"

@分析器母机.语法规则("各列声明 : 列声明 | 各列声明 逗号 列声明")
def 各列声明(片段):
    return f"{片段[0]}" if len(片段) == 1 else f"{片段[0]}, {片段[2]}"

@分析器母机.语法规则("表声明 : 创建 标识符 表")
def 表声明(片段):
    return f"CREATE TABLE {片段[1].getstr()}"

@分析器母机.语法规则("列声明 : 标识符 为 列类型 | 标识符 为 全部列特性 的 列类型")
def 列声明(片段):
    return f"{片段[0].getstr()} {片段[2]}" if len(片段) == 3 else f"{片段[0].getstr()} {片段[4]} {片段[2]}"

@分析器母机.语法规则("全部列特性 : 列特性 | 全部列特性 列特性")
def 列特性(片段):
    return f"{片段[0]}" if len(片段) == 1 else f"{片段[0]} {片段[1]}"

@分析器母机.语法规则("列特性 : 不为空 | 不重复")
def 列特性(片段):
    return "NOT NULL" if 片段[0].getstr()=="不为空" else "UNIQUE"

@分析器母机.语法规则("列类型 : 整数 | 文本")
def 列类型(片段):
    return "INTEGER" if 片段[0].getstr()=="整数" else "TEXT"

语法还没复杂到需要先生成抽象语法树的地步,直接用字符串拼接生成了。

有了这样的工具,感觉可以玩的多了不少。

完整测试源码 在此