【发布时间】:2016-07-02 12:17:26
【问题描述】:
我正在将一个 Ruby 项目转换为 Elixir。 Ruby 的 until 循环如何转化为 Elixir?
until scanner.eos? do
tokens << scan(line + 1)
end
这是完整的 Ruby 方法:
def tokenize
@tokens = []
@lines.each_with_index do |text, line|
@scanner = StringScanner.new(text)
until @scanner.eos? do
@tokens << scan(line + 1)
end
end
@tokens
end
@lines 只是一个由新行分割的文本文件。 @lines = text.split("\n")
在 Elixir 中,我已经转换了 string scanner,如下所示:StringScanner.eos?(scanner):
@spec eos?(pid) :: boolean
def eos?(pid) when is_pid(pid) do
此外,在 Elixir 中,标记是元组:@type token :: {:atom, any, {integer, integer}}。其中{integer, integer} 元组是令牌的line 和position。
这是 Elixir 伪代码,不太好用。
@spec scan(String.t, integer) :: token
def scan(text, line) when is_binary(text) and is_integer(line) do
string_scanner = StringScanner.new(text)
until StringScanner.eos?(string_scanner) do
result = Enum.find_value(@scanner_tokenizers, fn {scanner, tokenizer} ->
match = scanner.(string_scanner)
if match do
tokenizer.(string_scanner, match, line)
end
end)
IO.inspect result
end
StringScanner.stop(string_scanner)
result
end
slack channel 上的某人建议使用 recursion,但他们没有举例说明。我已经看到了使用累加器等的求和/减少的递归示例。但是,在评估布尔值时,我看不到它是如何应用的。
谁能提供一个使用StringScanner.eos?(scanner) 的工作示例?谢谢。
【问题讨论】:
-
我想说你问错问题了。请解释您的最终目标是什么,提出一个好的解决方案可能更容易。对我来说,现在的问题真的没有什么意义。
-
我有一个分词器,它将文本文件拆分为单独的行,然后循环遍历每一行,并给 StringScanner 一行,后者循环遍历行匹配模式。就像 Ruby 版本一样,字符串扫描器在每次扫描匹配时移动一个指针。 eos?如果已到达字符串的末尾,则返回 true。在 Ruby 中,我使用了
until循环。