【问题标题】:ANTLR grammar for scheme R5RS方案 R5RS 的 ANTLR 文法
【发布时间】:2013-06-29 03:44:24
【问题描述】:

我是 ANTLR 的初学者,我正在通过一个例子来学习它。我使用 C 作为我的目标语言。 示例是取自this question 的Scheme R5RS 语法文件,稍作修改(重命名语法名称并添加一些选项,语法规范不变)。

antlr 生成了词法分析器和解析器,我使用测试main() 对其进行编译,其中我只是进行一些初始化并简单地调用解析器。当使用一段方案代码运行测试程序时,解析器检测到一些语法错误(这不应该发生!)

main test.c 中的函数

#include <stdio.h>
#include "r5rsLexer.h"
#include "r5rsParser.h"

int main(int argc, char *argv[])
{
  pANTLR3_UINT8 fname;
  pANTLR3_INPUT_STREAM input;
  pr5rsLexer lexer;
  pANTLR3_COMMON_TOKEN_STREAM tstream;
  pr5rsParser parser;
  r5rsParser_parse_return parse_return;

  if (argc != 2)
    {
      ANTLR3_FPRINTF(stderr, "usage: %s file\n", argv[0]);
      exit(1);
    }
  fname = (pANTLR3_UINT8)argv[1];
  input = antlr3FileStreamNew(fname, ANTLR3_ENC_8BIT);
  if (!input)
    {
      ANTLR3_FPRINTF(stderr, "open file stream failed\n");
      exit(1);
    }
  lexer = r5rsLexerNew(input);
  if (!lexer)
    {
      ANTLR3_FPRINTF(stderr, "new lexer failed\n");
      exit(1);
    }
  tstream =
    antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lexer));
  if (!tstream)
    {
      ANTLR3_FPRINTF(stderr, "open token stream failed\n");
      exit(1);
    }
  parser = r5rsParserNew(tstream);
  if (!parser)
    {
      ANTLR3_FPRINTF(stderr, "new parser failed\n");
      exit(1);
    }
  parse_return = parser->parse(parser);
  printf("succeed!\n");
  return 0;
}

test.scm 中的方案代码:

(define-syntax should-be
  (syntax-rules ()
    ((_ test-id value expression)
     (let ((return-value expression))
         (if (not (equal? return-value value))
           (for-each (lambda (v) (display v))
                     `("Failure: " test-id ", expected '"
                     value "', got '" ,return-value "'." #\newline))
           (for-each (lambda (v) (display v))
                     '("Passed: " test-id #\newline)))))))
(should-be 1.1 0
 (let ((cont #f))
   (letrec ((x (call-with-current-continuation (lambda (c) (set! cont c) 0)))
            (y (call-with-current-continuation (lambda (c) (set! cont c) 0))))
     (if cont
         (let ((c cont))
           (set! cont #f)
           (set! x 1)
           (set! y 1)
           (c 0))
         (+ x y)))))

终端输出:

$> ls
r5rs.g test.c test.scm
$> antlr3 r5rs.g
$> ls
r5rs.g r5rs.tokens r5rsLexer.c r5rsLexer.h r5rsParser.c r5rsParser.h test.c test.scm
$> gcc -o test test.c r5rsLexer.c r5rsParser.c -lantlr3c
$> ./test test.scm
test.scm(1)  : error 4 : Unexpected token, at offset 0
near [Index: 1 (Start: 154513905-Stop: 154513917) ='define-syntax', type<5> Line:1 
LinePos:0]
: unexpected input...
expected one of : <EOR>
test.scm(2)  : error 4 : Unexpected token, at offset 3
near [Index: 8 (Start: 154513932-Stop: 154513943) ='syntax-rules', type<7> Line: 2 
LinePos:3]
: unexpected input...
expected one of : <EOR>
test.scm(2)  : error 4 : Unexpected token, at offset 17
near [Index: 11 (Start: 154513946-Stop: 154513946) =')', type<82> Line: 2 LinePos:17]
: unexpected input...
expected one of : <EOR>
test.scm(2)  : error 4 : Unexpected token, at offset 17
near [Index: 11 (Start: 154513946-Stop: 154513946) =')', type<82> Line: 2 LinePos:17]
: unexpected input...
expected one of : <EOR>

我已经阅读了语法规范,它是正确的。我无法弄清楚问题出在哪里......有人可以帮忙吗?谢谢!

======================回复=========================

按照patterntemplate的语法规则,我下到下面的代码片段。我认为解析将与 template 匹配并失败,因为 template 没有 quasiquote 替代。

`("Failure: " test-id ", expected '" value "', got '" ,return-value "'." #\newline)

我相信template的语法规则正确地遵循了R5RS规范,并且代码被其他R5Rs方案实现所接受(我在scheme48和guile中测试过)。怎么会这样?

我认为我的分析一定有问题......

【问题讨论】:

  • 您正在向后看。您有一段有效的方案代码和从 Internet 上获取的语法。虽然我承认语法看起来不错,但您显然发现了它没有涵盖的边缘情况。我认为你不应该质疑自己。
  • 好的,我想我还是把麻烦留在那里一会儿。非常感谢@Slartibartfast

标签: scheme antlr antlr3 r5rs


【解决方案1】:

这是一个反引号

`("Failure: " test-id ", expected '"

使解析器跳闸。

如果您遵循模式和模板的语法规则,您会发现它们无法达到同时匹配 QUASIQUOTE 和反引号的 quasiquotation 规则。但是,它们确实到达了包含 QUASIQUOTEexpressionKeyword

您应该修正语法以在模板中包含缩写形式,或者修正您的输入以不使用它们。

【讨论】:

  • 非常感谢! @Slartibartfast,但我仍然有麻烦......请参阅我的版本来回答上面的问题。
  • 抱歉,@Slartibartfast 我不知道为什么我的版本没有生效。我已经编辑了我的原始帖子以包含我的问题。
猜你喜欢
  • 2012-03-16
  • 2014-07-28
  • 1970-01-01
  • 2012-10-28
  • 1970-01-01
  • 2015-03-24
  • 2012-09-06
  • 2019-03-25
  • 1970-01-01
相关资源
最近更新 更多