方案 R5RS 的 ANTLR 语法 [英] ANTLR grammar for scheme R5RS

查看:22
本文介绍了方案 R5RS 的 ANTLR 语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm beginner in ANTLR and I'm learning it by an example. I use C as my target language. The example is a Scheme R5RS grammar file taken from this question, with a little modification(rename the grammar name and add some options with the grammar specification untouched).

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

antlr generated the lexer and parser, and I compile it with a test main() in which I just do some initialization and simply call the parser. When runing the test program with a piece of scheme code, the parser detect some syntax error(which should not happen!)

main test.c 中的函数

main function in 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 中的方案代码:

scheme code in 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>

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

I've read through the grammar specification and it is correct. I can't figure out where the problem lies ... can someone help? thanks!

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

===================== reply =========================

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

Following the grammar rule of pattern and template, I went down to the code fragment below. I think the parse is going to match template with it and failed because template doesn't have an quasiquote alternative.

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

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

I believe the grammar rule for template follows the R5RS specification correctly, and the code is accepted by other R5Rs scheme implementation(I tested it in scheme48 and guile). How can this happen?

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

I think there must be something wrong in my analyse ...

推荐答案

这是一个反引号

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

使解析器跳闸.

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

If you follow grammar rules for pattern and template, you'll see that they don't reach quasiquotation rule that match both QUASIQUOTE and back-tick. They do however reach expressionKeyword that contains QUASIQUOTE.

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

You should fix grammar to include abbreviated forms in template or fix your input not to use them.

这篇关于方案 R5RS 的 ANTLR 语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆