我正在尝试编写一个迭代的LL( k )解析器,并且我已经很好地解决了字符串,因为它们有一个开始和结束标记,所以你可以{{{ 1}}。
但是,数字不会,而且只包含"".join(tokenlist[string_start:string_end])
。它们可以出现在程序中的任何给定点,具有任意长度并且仅由非数字限定。
一些例子,因为这个定义很模糊:
.0123456789
我试图解决的问题是解析器应该如何确定数字文字的结束位置。 (请注意,这是一个无上下文,自我修改的解释语法,因此没有单独的词法分析。)
我可以通过迭代解决这个问题:
56 123.45/! is 56 and 123.45 followed by two other tokens
565.5345.345 % is 565.5345, 0.345 and two other tokens (incl. whitespace)
(我认为我不需要澄清变量,因为它是一个例子而且非常简单。)
大!这有效,但至少有两个问题:
对于数字长度 n 的数字,它是 O(n)。 不理想。*
此方法所属的解析器类已经使用def _next_notinst(self, atindex, subs = DIGITS):
"""return the next index of a char not in subs"""
for i, e in enumerate(self.toklist[atindex:]):
if e not in subs:
return i - len(self.toklist)
else:
break
return self.idx.v
来循环遍历字符串的任意部分,我希望不具有远程嵌套循环当我不需要来。
来自上一篇文章:由于解析器使用任意 k 前瞻和跳过,parsing each individual token is absolutely not what I want。
我不想使用RegEx主要是因为我不知道它,现在使用它会使我的代码无法理解 me ,它的创建者。
必须有一个简单的< O(n)解决方案,它只是在给定起点的字符串中收集连续数字,直到非数字为止。
*是的,我完全清楚解析器本身是 O(n),但我们 还需要链接器是> O(n)的。如果您不相信我,则字符串链接器是 O(1),因为它只是在程序中查找下一个未转义的while True:
,然后将所有字符连接到该字符串。我不能为数字做同样的事情吗?
答案 0 :(得分:0)
由于缺乏测试,我的其他答案实际上是错误的。
我决定把它吸收并学习一点RegEx,因为这是解决这个问题的唯一方法。
^([.\d]+[.\d]+|[.\d])
适用于我想要的内容,并与之匹配:
123.43.453""
.234234!/%
但不是,例如:
"1233