1

使用文件“test-lexer.lisp”,我稍微修改了lex

(defparameter *lex* (test-lexer "{ 1.0 12 fred 10.23e12"))

并将测试重复的次数增加到 6

(defun test ()
  (loop repeat 6
 collect (multiple-value-list (funcall *lex*))))

并尝试以多种方式修改 test-lexer 以尝试使其将“{”识别为标记。

例如,在 (deflexer test-lexer ...) 中添加 [:punct:]

通过改变

("[:alpha:][:alnum:]*"
  (return (values 'name %0)))

("[:alpha:][:alnum:][:punct:]*"
   (return (values 'name %0)))

并不断收到错误,例如

"""Lexer 无法识别 "{ 1.0 12 fred 10.23e12" 中的标记,位置 0 ("{ 1.0 12 fred 10.23e") [SIMPLE-ERROR 类型的条件]"""

如何将“{”指定为要识别的字符?还是我的问题在别处?

4

1 回答 1

2

cl-lexer系统基于正则表达式,因此您可以使用任何文字字符来代表自己,例如{. 但是恰好大括号字符在正则表达式语言中具有特殊含义,所以需要用反斜杠将其引用。为了在 Lisp 字符串中编写反斜杠,需要对反斜杠进行转义。因此:

(deflexer test-lexer
  ("\\{"  (return (values :grouping :open-brace)))  ;; <-- Here
  ("[0-9]+([.][0-9]+([Ee][0-9]+)?)"
   (return (values 'flt (num %0))))
  ("[0-9]+"
   (return (values 'int (int %0))))
  ("[:alpha:][:alnum:]*"
   (return (values 'name %0)))
  ("[:space:]+"))

我返回:open-brace值和:grouping类别,但如果需要,您可以选择返回其他内容。然后测试函数返回:

((:GROUPING :OPEN-BRACE) (FLT 1.0) (INT 12)
 (NAME "fred") (FLT 1.023e13) (NIL NIL))
于 2017-02-19T06:07:07.587 回答