我想在非关系数据存储之上创建一个SQL接口.非关系数据存储,但以关系方式访问数据是有意义的.
我正在研究使用ANTLR生成一个AST,它将SQL表示为关系代数表达式.然后通过评估/遍历树来返回数据.
我之前从未实现过解析器,因此我想就如何最好地实现SQL解析器和求值程序提出一些建议.
更新:
我使用pyparsing实现了一个简单的SQL解析器.结合对我的数据存储实现关系操作的Python代码,这非常简单.
正如我在其中一条评论中所说,演习的重点是将数据提供给报告引擎.为此,我可能需要实现ODBC驱动程序.这可能是很多工作.
我想为包含几个部分的文件创建一个语法(如下面的PARAGRAPH).
一个部分以其关键字(例如PARAGRAPH)开头,后跟一个标题(此处为标题),其内容在以下行中,一行内容是该部分的一行.它就像一个带有标题,列和行的表.
在下面的示例(tablefile)中,我将限制部分包含一列和一行.
tablefile := paragraph*
paragraph := PARAGRAPH title CR
TAB content
title, content := \w+
Run Code Online (Sandbox Code Playgroud)
由于我需要处理换行符和表格,我需要将默认空格设置为''.
def grammar():
'''
Bottom-up grammar definition
'''
ParserElement.setDefaultWhitespaceChars(' ')
TAB = White("\t").suppress()
CR = LineEnd().setName("Carriage Return").suppress()
PARAGRAPH = 'PARAGRAPH'
title = Word(alphas)
content = Word(alphas)
paragraph = (PARAGRAPH + title + CR
+ TAB + content)
tablefile = OneOrMore(paragraph)
tablefile.parseWithTabs()
return tablefile
Run Code Online (Sandbox Code Playgroud)
这个虚拟示例很容易匹配:
PARAGRAPH someTitle
thisIsContent
Run Code Online (Sandbox Code Playgroud)
另外这个:
PARAGRAPH someTitle
thisIsContent
PARAGRAPH otherTitle
thisIsOtherContent
Run Code Online (Sandbox Code Playgroud)
它PARAGRAPH在第一个内容之后等待,并偶然发现换行符(记住setDefaultWhitespaceChars(' ')).我是否被迫 …
好的,所以我问过一些关于这个项目的小问题,但我对我想出的设计仍然没有多少信心,所以我会在更广泛的范围内提出一个问题.
我正在解析课程目录的先决条件描述.描述几乎总是遵循某种形式,这使我认为我可以解析其中的大多数.
从文本中,我想生成一个关于课程必备关系的图表.(在我解析数据之后,那部分会很简单.)
一些样本输入和输出:
"CS 2110" => ("CS", 2110) # 0
"CS 2110 and INFO 3300" => [("CS", 2110), ("INFO", 3300)] # 1
"CS 2110, INFO 3300" => [("CS", 2110), ("INFO", 3300)] # 1
"CS 2110, 3300, 3140" => [("CS", 2110), ("CS", 3300), ("CS", 3140)] # 1
"CS 2110 or INFO 3300" => [[("CS", 2110)], [("INFO", 3300)]] # 2
"MATH 2210, 2230, 2310, or 2940" => [[("MATH", 2210), ("MATH", 2230), ("MATH", 2310)], [("MATH", 2940)]] # 3
Run Code Online (Sandbox Code Playgroud)
如果整个描述只是一个过程,则直接输出.
如果课程是连接的("和"),则它们都输出在同一列表中
如果课程脱离("或"),则它们位于不同的列表中
在这里,我们有"和"和"或". …
我正在构建一个名为C--(不是实际的C语言)的虚构编程语言的解析器.我已经到了需要将语言的语法翻译成Pyparsing可以接受的东西的阶段.不幸的是,当我来解析我的输入字符串(这是正确的,不应该导致Pyparsing错误)时,它没有正确解析.我担心这是由于我的语法错误,但是当我第一次开始Pyparsing时,我似乎无法看到我出错的地方.
我上传我是从翻译语法这里的人们有一个读通过.
编辑:更新了保罗的建议.
这是我目前得到的语法(我知道,语法定义的两个顶线对我来说非常糟糕):
# Lexical structure definition
ifS = Keyword('if')
elseS = Keyword('else')
whileS = Keyword('while')
returnS = Keyword('return')
intVar = Keyword('int')
voidKeyword = Keyword('void')
sumdiff = Literal('+') | Literal('-')
prodquot = Literal('*') | Literal('/')
relation = Literal('<=') | Literal('<') | Literal('==') | \
Literal('!=') | Literal('>') | Literal('=>')
lbrace = Literal('{')
rbrace = Literal('}')
lparn = Literal('(')
rparn = Literal(')')
semi = Literal(';')
comma = Literal(',')
number = Word(nums)
identifier = Word(alphas, alphanums)
# Syntax …Run Code Online (Sandbox Code Playgroud) 作为大型纯Python应用程序的一部分,我为pyparsing开发了一个巨大的语法.我已经达到了性能调整的极限,我正处于收益递减让我开始寻找其他地方的地步.是的,我想我知道大部分提示和技巧,并且我已经将我的语法和应用程序描述为灰尘.
接下来是什么?
我希望找到一个解析器,它给我相同的可读性,可用性(我使用许多高级的pyparsing功能,如parse-actions来启动正在解析的输入的后处理)和python集成但是在10×表现.
我喜欢语法是纯Python的事实.
我所有的基本块都是正则表达式,所以重用它们会很好.
我知道我不能拥有所有东西所以我愿意放弃今天的一些功能来达到要求的10倍性能.
我从哪里开始?
我试图解析复杂的逻辑表达式,如下所示;
x > 7 AND x < 8 OR x = 4
Run Code Online (Sandbox Code Playgroud)
并将解析后的字符串作为二叉树.对于上面的表达式,预期的解析表达式应如下所示
[['x', '>', 7], 'AND', [['x', '<', 8], 'OR', ['x', '=', 4]]]
Run Code Online (Sandbox Code Playgroud)
'OR'逻辑运算符的优先级高于'AND'运算符.括号可以覆盖默认优先级.更一般地说,解析后的表达式应该是这样的;
<left_expr> <logical_operator> <right_expr>
Run Code Online (Sandbox Code Playgroud)
另一个例子是
input_string = x > 7 AND x < 8 AND x = 4
parsed_expr = [[['x', '>', 7], 'AND', ['x', ',', 8]], 'AND', ['x', '=', 4]]
Run Code Online (Sandbox Code Playgroud)
到目前为止,我想出了这个简单的解决方案,遗憾的是它无法以二叉树方式生成解析表达式.operatorPrecedence似乎没有帮助我这里有连续相同的逻辑运算符,如前面的例子.
import pyparsing as pp
complex_expr = pp.Forward()
operator = pp.Regex(">=|<=|!=|>|<|=").setName("operator")
logical = (pp.Keyword("AND") | pp.Keyword("OR")).setName("logical")
vars = pp.Word(pp.alphas, pp.alphanums + "_") | pp.Regex(r"[+-]?\d+(:?\.\d*)?(:?[eE][+-]?\d+)?")
condition …Run Code Online (Sandbox Code Playgroud) 我已经尝试使用这段代码并将其转换为我正在编写的用于编程语言处理的项目,但我遇到了一个简化版本的问题:
op = oneOf( '+ - / *')
lparen, rparen = Literal('('), Literal(')')
expr = Forward()
expr << ( Word(nums) | ( expr + op + expr ) | ( lparen + expr + rparen) )
Run Code Online (Sandbox Code Playgroud)
我已经玩过这个简单设置的许多不同修改.通常,尝试以下方式:
print(expr.parseString('1+2'))
Run Code Online (Sandbox Code Playgroud)
会回来['1'].虽然我陷入了深度递归中,例如:
print(expr.parseString('(1+2)'))
Run Code Online (Sandbox Code Playgroud)
关于简单的递归而我无法解释的是我无法解析任意的算术表达式,例如1+(2 * 3-(4*(5+6)-(7))...?
我正在尝试解析一个简单的key = value查询语言.我实际上是用一个巨大的怪物解析器完成它,然后我再次通过来清理解析树.我想要做的是从下往上,其中包括像使用套为划清解析(KEY,VAL)对,这样对冗余消除等,虽然我之前的工作,我不觉得就像我完全理解为什么pyparsing按照它的方式行事,所以我做了大量的工作等等,有点像对抗谷物.
目前,这是我的"简化"解析器的开头:
from pyparsing import *
bool_act = lambda t: bool(t[0])
int_act = lambda t: int(t[0])
def keyval_act(instring, loc, tokens):
return set([(tokens.k, tokens.v)])
def keyin_act(instring, loc, tokens):
return set([(tokens.k, set(tokens.vs))])
string = (
Word(alphas + '_', alphanums + '_')
| quotedString.setParseAction( removeQuotes )
)
boolean = (
CaselessLiteral('true')
| CaselessLiteral('false')
)
integer = Word(nums).setParseAction( int_act )
value = (
boolean.setParseAction(bool_act)
| integer
| string
)
keyval = (string('k') + Suppress('=') + value('v')
).setParseAction(keyval_act)
keyin = (
string('k') + …Run Code Online (Sandbox Code Playgroud) 我想使用pyparsing来解析表单的表达式:expr = '(gimme [some {nested [lists]}])',并返回一个表单的python列表:[[['gimme', ['some', ['nested', ['lists']]]]]].现在我的语法看起来像这样:
nestedParens = nestedExpr('(',')')
nestedBrackets = nestedExpr('[',']')
nestedCurlies = nestedExpr('{','}')
included = nestedParens | nestedBrackets | nestedCurlies
目前, enclosed.searchString(expr)返回一个表单列表:[[['gimme', ['some', '{nested', '[lists]}']]]].这不是我想要的,因为它不能识别正方形或花括号,但我不知道为什么.
:)我尝试使用w = Word(printables),但它无法正常工作.我应该如何给出这个规范.'w'用于处理印地语字符(UTF-8)
代码指定语法并相应地解析.
671.assess :: ????? ::2
x=number + "." + src + "::" + w + "::" + number + "." + number
Run Code Online (Sandbox Code Playgroud)
如果它只有英文字符,那么代码对于ascii格式是正确的,但代码不适用于unicode格式.
我的意思是当我们有671.assess :: ahsaas :: 2形式的代码时代码可以工作
即它解析英文格式的单词,但我不知道如何解析然后以unicode格式打印字符.我需要这个用于英语印地语单词对齐的目的.
python代码如下所示:
# -*- coding: utf-8 -*-
from pyparsing import Literal, Word, Optional, nums, alphas, ZeroOrMore, printables , Group , alphas8bit ,
# grammar
src = Word(printables)
trans = Word(printables)
number = Word(nums)
x=number + "." + src + "::" + trans + "::" + number + "." + …Run Code Online (Sandbox Code Playgroud)