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

查看:152
本文介绍了方案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函数

#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天全站免登陆