2

私はANTLRの初心者で、例で学んでいます。私はターゲット言語として C を使用しています。この例は、この質問から取得したScheme R5RS文法ファイルで、少し変更されています(文法名を変更し、文法仕様を変更せずにいくつかのオプションを追加します)。

antlr はレクサーとパーサーを生成し、main()初期化を行ってパーサーを呼び出すだけのテストでコンパイルします。スキーム コードの一部を使用してテスト プログラムを実行すると、パーサーが何らかの構文エラーを検出します (これは発生してはなりません!)。

maintest.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>

文法仕様を読みましたが、正しいです。問題がどこにあるのかわかりません...誰か助けてくれますか?ありがとう!

===================== 返信 =========================

patternとの文法規則に従って、template以下のコード フラグメントに進みました。解析はそれと一致し、代替手段がないtemplateため失敗したと思います。templatequasiquote

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

の文法規則templateは R5RS 仕様に正しく準拠しており、コードは他の R5R スキーム実装で受け入れられていると思います (Scheme48 と Guile でテストしました)。これはどのように起こりますか?

私の分析に何か問題があるに違いないと思います...

4

1 に答える 1