【问题标题】:Scheme - LALR parser generation- input from a string方案 - LALR 解析器生成 - 来自字符串的输入
【发布时间】:2012-11-04 00:13:16
【问题描述】:

我们正在尝试(以诡计)生成一个解析器和一个从字符串而不是标准输入读取字符的词法分析器。

我们开始修改代码中包含的计算器示例 http://code.google.com/p/lalr-scm/source/browse/trunk/calc.scm?r=52

问题似乎出在以下行:

(let* ((location (make-source-location "*stdin*" 
(port-line (current-input-port)) 
(port-column (current-input-port)) -1 -1))

我们尝试定义一个新的输入端口:

(let* ((location (make-source-location "*stdin*" 
(port-line (open-input-string program)) 
(port-column (open-input-string program)) -1 -1))

而变量program是这样定义的:

(define program
"int x = 2;
 int y = 0;
 y= x*(2+3);"
 )     

但它不起作用,它仍然在等待标准输入字符。

文档缺乏细节,所以我们无法弄清楚如何解决这个问题。

谢谢

【问题讨论】:

  • Chris Jester-Young 关于 Scheme 中的大多数 I/O 如何使用默认的 current-input-port 的注释是正确的。您需要将字符串端口显式传递给每个 I/O 函数。请参阅read-char 的文档,例如:gnu.org/software/guile/manual/guile.html#Reading。请注意,port 参数在括号中:这是文档对“可选参数”的表示法。

标签: parsing scheme lalr guile


【解决方案1】:

您非常非常接近解决方案!嗯,有点。但这是一个开始。查看原始代码,在你修改它的地方:

(let* ((location (make-source-location "*stdin*" (port-line (current-input-port)) (port-column (current-input-port)) -1 -1))
       (c (read-char)))
  ...)

在这里,您将所有(current-input-port) 更改为您的字符串端口(顺便说一句,不要多次调用open-input-string,因为您每次都创建一个新的字符串端口,每个都有独立的光标),但这不是唯一实际使用(current-input-port)的地方。

你看到了吗?它实际上在(read-char) 电话中!该函数实际上接受一个端口参数,默认为(current-input-port)

事实上,如果您查看上方并搜索@​​987654327@ 和(peek-char) 的实例,您会注意到(current-input-port) 的使用几乎融入了整个make-lexer 函数。所以你需要改变它。

我建议您为make-lexer 函数指定一个输入端口:

(define* (make-lexer errorp #:optional (input (current-input-port)))
  ...

然后更改(read-char)(peek-char)所有 个实例以使用输入端口。也不要忘记更改您的make-source-location 电话:

(let* ((location (make-source-location "*stdin*" (port-line input) (port-column input) -1 -1))
       (c (read-char input)))
  ...)

现在,您可以使用(make-lexer errorp (open-input-string program)),它应该可以工作了。 (我没有测试过。)

【讨论】:

  • 嗨,谢谢你的回答,我试着按照你说的做,但是我得到这个错误: In expression (define* (make-lexer errorp # ...)) Unbound variable: define *。你知道问题出在哪里了吗?
  • 您使用的是什么版本的 Guile?如果是 1.x,则需要在程序顶部使用 (use-modules (ice-9 optargs))。 (Guile 2.x 已经内置了define*。)
  • 我使用的是 1.8,而我的一个朋友使用的是 2.0 并且它可以工作......所以今晚我将导入(使用模块(ice-9 optargs))......谢谢你非常克里斯!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-21
  • 2023-03-19
相关资源
最近更新 更多