我正在尝试在Racket中创建一种新语言,其中语句分开。换行符定义语句的结尾和新语句的开头。
我仔细阅读了本指南的Create Languages章节,该章节非常有用,但这些示例的重点是扩展类似s-exp的语言。我看到的唯一选择是为read
和read-syntax
手动编写自己的解析器。
我希望使用readtables,但我不知道是否可以。我试过了:
(make-readtable #f #f 'non-terminating-macro my-read-line-fn)
但我不知道这是否有多大帮助。我想我可以创建一个子可读表来执行read-word
,read-string
这样的事情,我会根据my-read-line-fn
得到的字符来调度它。
这是最好的策略还是预定的阅读方式直到行尾?
答案 0 :(得分:1)
我认为你不需要对可读表做任何事情。您的lang / reader.rkt可以提供您自己的read-syntax
,可以根据需要进行读取/解析,并且可能会在遇到EOL时停止。
一个有趣的例子是Brainfudge。它的概念"陈述"是单个字符,但IIUC也[
括号]
。
请参阅其lang / reader.rkt和parser.rkt获取低级别位,然后尝试了解它最终如何评估为Racket表达式。
答案 1 :(得分:1)
您确实需要编写解析语言的读取和读取语法版本。 readtable仅用于修改内置读取,因此我建议您查看解析器工具(http://docs.racket-lang.org/parser-tools/index.html),它是以lex / yacc样式编写解析器的工具。
另一种方法是使用ragg:
http://www.hashcollision.org/ragg/
使用DrRacket中的包管理器安装Ragg。在可用包列表中搜索ragg。
答案 2 :(得分:1)
创建自己的reader.rkt:
#lang s-exp syntax/module-reader
(test test)
#:read-syntax my-read-syntax
#:read my-read
;; override default read (won't be used but is required)
(define (my-read in) (read-line in))
;; override read-syntax by reading in one string at a time and
;; pass it to statement-string->code to get code as dara and
;; make it syntax with datum->syntax
(define (my-read-syntax in)
(datum->syntax #f (statement-string->code (read-line in))))
;; This is actually how you want your code
;; to become s-expressions. I imagine that my
;; module has a primitive called code that
;; interprets the string as is
(define (statement-string->code str)
(list 'code str))
答案 3 :(得分:-1)
球拍没有"陈述",因此新线的概念结束"陈述"是荒谬的。
如果你的动机是减少或取消括号,我鼓励你使用标准替代品"像sweet-expressions这样的读者,而不是制作本土的东西。