sam*_*ing 7 python sql parsing ply context-free-grammar
我知道还有其他工具来解析SQL语句,但我出于教育目的推出了自己的工具.我现在卡住了我的语法..如果你能快速发现错误请告诉我.
SELECT = r'SELECT'
FROM = r'FROM'
COLUMN = TABLE = r'[a-zA-Z]+'
COMMA = r','
STAR = r'\*'
END = r';'
t_ignore = ' ' #ignores spaces
statement : SELECT columns FROM TABLE END
columns : STAR
| rec_columns
rec_columns : COLUMN
| rec_columns COMMA COLUMN
Run Code Online (Sandbox Code Playgroud)
当我尝试解析像'SELECT a FROM b;'这样的语句时 我在FROM令牌上遇到语法错误...非常感谢任何帮助!
(编辑)代码:
#!/usr/bin/python
import ply.lex as lex
import ply.yacc as yacc
tokens = (
'SELECT',
'FROM',
'WHERE',
'TABLE',
'COLUMN',
'STAR',
'COMMA',
'END',
)
t_SELECT = r'select|SELECT'
t_FROM = r'from|FROM'
t_WHERE = r'where|WHERE'
t_TABLE = r'[a-zA-Z]+'
t_COLUMN = r'[a-zA-Z]+'
t_STAR = r'\*'
t_COMMA = r','
t_END = r';'
t_ignore = ' \t'
def t_error(t):
print 'Illegal character "%s"' % t.value[0]
t.lexer.skip(1)
lex.lex()
NONE, SELECT, INSERT, DELETE, UPDATE = range(5)
states = ['NONE', 'SELECT', 'INSERT', 'DELETE', 'UPDATE']
current_state = NONE
def p_statement_expr(t):
'statement : expression'
print states[current_state], t[1]
def p_expr_select(t):
'expression : SELECT columns FROM TABLE END'
global current_state
current_state = SELECT
print t[3]
def p_recursive_columns(t):
'''recursive_columns : recursive_columns COMMA COLUMN'''
t[0] = ', '.join([t[1], t[3]])
def p_recursive_columns_base(t):
'''recursive_columns : COLUMN'''
t[0] = t[1]
def p_columns(t):
'''columns : STAR
| recursive_columns'''
t[0] = t[1]
def p_error(t):
print 'Syntax error at "%s"' % t.value if t else 'NULL'
global current_state
current_state = NONE
yacc.yacc()
while True:
try:
input = raw_input('sql> ')
except EOFError:
break
yacc.parse(input)
Run Code Online (Sandbox Code Playgroud)
我觉得你的问题是,你的正则表达式t_TABLE
,并t_COLUMN
也符合保留字(SELECT和FROM)。换句话说,将SELECT a FROM b;
令牌化为类似的符号COLUMN COLUMN COLUMN COLUMN END
(或其他一些模棱两可的令牌化),而这与您的任何生产都不匹配,因此会出现语法错误。
快速检查一下,更改这些正则表达式以使其完全匹配您输入的内容,如下所示:
t_TABLE = r'b'
t_COLUMN = r'a'
Run Code Online (Sandbox Code Playgroud)
您会看到语法SELECT a FROM b;
通过,因为正则表达式'a'和'b'与您的保留字不匹配。
而且,还有另一个问题,就是TABLE和COLUMN的正则表达式也重叠,因此词法分析器也不能在不混淆这些标记的情况下进行标记化。
PLY文档中有一个微妙但相关的部分。不确定最好的解释方式,但是诀窍是令牌化过程首先发生,因此它不能真正使用生产规则中的上下文来了解它是否遇到了TABLE令牌或COLUMN令牌。您需要将其归纳为某种ID
标记,然后在解析过程中将其清除。
如果我有更多的精力,我会尝试更多地处理您的代码并提供代码中的实际解决方案,但是我认为,既然您已经表达了这是一次学习练习,也许您会满意我的意思正确的方向。
归档时间: |
|
查看次数: |
2031 次 |
最近记录: |