Parsing 球拍-使用令牌字符定义一个字符
我正在为一个类做一个项目,我们的任务是用Python和Racket编写数字、符号、注释、算术运算符、括号和EOF的扫描器。我正在制作球拍版本,我已经写了以下行来定义一个或多个字符作为符号:Parsing 球拍-使用令牌字符定义一个字符,parsing,token,racket,Parsing,Token,Racket,我正在为一个类做一个项目,我们的任务是用Python和Racket编写数字、符号、注释、算术运算符、括号和EOF的扫描器。我正在制作球拍版本,我已经写了以下行来定义一个或多个字符作为符号: [(any-char) (token-CHAR (string->character lexeme))] 我有以下行将一个或多个数字定义为数字: [(:+ digit) (token-NUM (string->number lexeme))] 我对球拍很陌生,这是我的第三个节目,所以我不确定该
[(any-char) (token-CHAR (string->character lexeme))]
我有以下行将一个或多个数字定义为数字:
[(:+ digit) (token-NUM (string->number lexeme))]
我对球拍很陌生,这是我的第三个节目,所以我不确定该怎么做,所以任何建议都非常感谢。我翻遍了球拍文档,但没能找到我要找的东西
谢谢 这里是一个简单的入门示例-大量评论
#lang racket
;;; IMPORT
;; Import the lexer tools
(require parser-tools/yacc
parser-tools/lex
(prefix-in : parser-tools/lex-sre) ; names from lex-sre are prefixed with :
; to avoid name collisions
syntax/readerr)
;;; REGULAR EXPRESSIONS
;; Names for regular expressions matching letters and digits.
;; Note that :or are prefixed with a : due to (prefix-in : ...) above
(define-lex-abbrevs
[letter (:or (:/ "a" "z") (:/ #\A #\Z) )]
[digit (:/ #\0 #\9)])
;;; TOKENS
;; Tokens such as numbers (and identifiers and strings) carry a value
;; In the example only the NUMBER token is used, but you may need more.
(define-tokens value-tokens (NUMBER IDENTIFIER STRING))
;; Tokens that don't carry a value.
(define-empty-tokens op-tokens (newline := = < > + - * / ^ EOF))
;;; LEXER
;; Here the lexer (aka the scanner) is defined.
;; The construct lexer-src-pos evaluates to a function which scans an input port
;; returning one position-token at a time.
;; A position token contains besides the actual token also source location information
;; (i.e. you can see where in the file the token was read)
(define lex
(lexer-src-pos
[(eof) ; input: eof of file
'EOF] ; output: the symbol EOF
[(:or #\tab #\space #\newline) ; input: whitespace
(return-without-pos (lex input-port))] ; output: the next token
; (i.e. skip the whitespace)
[#\newline ; input: newline
(token-newline)] ; ouput: a newline-token
; ; note: (token-newline) returns 'newline
[(:or ":=" "+" "-" "*" "/" "^" "<" ">" "=") ; input: an operator
(string->symbol lexeme)] ; output: corresponding symbol
[(:+ digit) ; input: digits
(token-NUMBER (string->number lexeme))])) ; outout: a NUMBER token whose value is
; ; the number
; ; note: (token-value token)
; returns the number
;;; TEST
(define input (open-input-string "123+456"))
(lex input) ; (position-token (token 'NUMBER 123) (position 1 #f #f) (position 4 #f #f))
(lex input) ; (position-token '+ (position 4 #f #f) (position 5 #f #f))
(lex input) ; (position-token (token 'NUMBER 456) (position 5 #f #f) (position 8 #f #f))
(lex input) ; (position-token 'EOF (position 8 #f #f) (position 8 #f #f))
;; Let's make it a little easier to play with the lexer.
(define (string->tokens s)
(port->tokens (open-input-string s)))
(define (port->tokens in)
(define token (lex in))
(if (eq? (position-token-token token) 'EOF)
'()
(cons token (port->tokens in))))
(map position-token-token (string->tokens "123*45/3")) ; strip positions
; Output:
; (list (token 'NUMBER 123)
; '*
; (token 'NUMBER 45)
; '/
; (token 'NUMBER 3))
#朗球拍
;;; 进口
;; 导入lexer工具
(需要解析器工具/yacc)
解析器工具/lex
(前缀:parser tools/lex sre);lex sre中的名称前缀为:
;以避免名称冲突
语法/读取错误)
;;; 正则表达式
;; 匹配字母和数字的正则表达式的名称。
;; 注意:或由于上面的(前缀in:…)而以:作为前缀
(定义法)
[字母(:或(:/“a”“z”)(:/\a\z))]
[数字(:/\0\9)])
;;; 代币
;; 数字(以及标识符和字符串)等标记携带值
;; 在本例中,仅使用数字标记,但您可能需要更多。
(定义标记值标记(数字标识符字符串))
;; 没有价值的代币。
(定义空令牌操作令牌(换行符:=<>+-*/^EOF))
;;; 雷克瑟
;; 这里定义了lexer(又名扫描器)。
;; 构造lexer src pos的计算结果是一个扫描输入端口的函数
;; 一次返回一个职位令牌。
;; 位置标记除了包含实际标记外,还包含源位置信息
;; (即,您可以看到令牌在文件中的读取位置)
(定义法律)
(lexer src位置
[(eof);输入:文件的eof
'EOF];输出:符号EOF
[(:或#\tab#\space#\newline);输入:空白
(返回时不带pos(lex输入端口))];输出:下一个令牌
(即跳过空格)
[#\newline;输入:newline
(标记换行符)];输出:换行符
;注意:(标记换行符)返回“换行符”
[(:或“:”+“”-“*”/”^=“=”);输入:运算符
(字符串->符号词素)];输出:对应符号
[(:+位);输入:位
(令牌编号(字符串->数字词素)));outout:值为的数字标记
; ; 号码
; ; 注:(令牌值令牌)
; 返回数字
;;; 试验
(定义输入(打开输入字符串“123+456”))
(法律输入);(位置标记(标记编号123)(位置1#f#f)(位置4#f))
(法律输入);(位置标记“+(位置4#f#f)(位置5#f))
(法律输入);(位置标识(标识号456)(位置5#f#f)(位置8#f))
(法律输入);(位置标记'EOF(位置8#f#f)(位置8#f#f))
;; 让我们更容易地使用lexer。
(定义(字符串->标记)
(端口->令牌(打开输入字符串)))
(定义(端口->中的令牌)
(定义令牌(lex-in))
(如果(等式?(位置标记)'EOF)
'()
(cons令牌(端口->中的令牌)))
(地图位置标记(字符串->标记“123*45/3”);剥离位置
; 输出:
; (列表(令牌编号123)
; '*
; '/
((代币"编号3))