Tôi biết có các công cụ khác để phân tích cú pháp câu lệnh SQL, nhưng tôi đang triển khai các mục đích giáo dục của riêng mình. Tôi đang bị mắc kẹt với ngữ pháp của tôi ngay bây giờ .. Nếu bạn có thể phát hiện ra một lỗi thực sự nhanh chóng xin vui lòng cho tôi biết.Sử dụng PLY để phân tích cú pháp câu lệnh 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
Khi tôi cố gắng phân tích cú pháp câu lệnh như 'CHỌN TỪ b;' Tôi nhận được lỗi cú pháp tại mã thông báo FROM ... Bất kỳ trợ giúp nào đều được đánh giá cao!
(Chỉnh sửa) Code:
#!/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)
Điều gì xảy ra nếu bạn đặt dấu cách giữa 'b' và'; '? – zerkms
Vẫn còn kết quả tương tự, tôi quên thêm rằng nó bỏ qua các khoảng trống ... Tôi sẽ chỉnh sửa điều đó. – sampwing
Theo như tôi biết, hầu hết các cơ sở dữ liệu sẽ hỗ trợ ít nhất '[a-zA-Z_0-9]' làm bảng tên. – NullUserException