【发布时间】:2014-07-26 10:43:22
【问题描述】:
我正在尝试使用 clojure 标记字符串。基本标记化规则要求将字符串拆分为单独的符号,如下所示:
- “hello world”形式的字符串文字是单个标记
- 不属于字符串文字的每个单词都是一个标记
- 每个非单词字符都是一个单独的标记
例如,给定字符串:
length=Keyboard.readInt("HOW MANY NUMBERS? ");
我希望它被标记为:
["length" "=" "Keyboard" "." "readInt" "(" "\"HOW MANY NUMBERS? \"" ")" ";"]
我已经能够根据上面的规则 2 和 3 编写一个函数来拆分字符串。我无法满足第一条规则。 意思是,目前上面的字符串拆分如下:
["let" "length" "=" "Keyboard" "." "readInt" "(" "\"HOW" "MANY" "NUMBERS?" "\"" ")" ";"]
这是我的功能:
(defn TokenizeJackLine [LineOfJackFile]
(filter not-empty
(->
(string/trim LineOfJackFile)
; get rid of all comments
(string/replace #"(//.*)|(\s*/?\*.*?($|\*/))|([^/\*]*\*/)" "")
; split into tokens using 0-width look-ahead
(string/split #"\s+|(?<=[\{\}\(\)\[\]\.,;+\-\*/&\|<>=~])|(?=[\{\}\(\)\[\]\.,;+\-\*/&\|<>=~])")
)))
如何编写一个函数,将字符串拆分为符合上述所有三个规则的标记?或者,我应该采取什么其他方法来实现所需的标记化?谢谢。
【问题讨论】:
-
而不是正则表达式(错误的工作工具!)我建议使用 instaparse。 github.com/Engelberg/instaparse
-
@progo 谢谢,但如果能找到一个简单的内置方法来做到这一点,那就太好了。
-
只有一个好的解析器才能让解析变得简单。
-
@noisesmith 我现在不想解析字符串,而是将其拆分为标记。
-
lexing 是一个实现细节,一些解析器(如 yacc)有单独的词法分析阶段,有些(如 clojure 的 instaparse)不分离这些阶段