ANTLR grammar for scheme R5RS

跟風遠走 提交于 2019-12-10 11:25:17

问题


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 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 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;
}

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)))))

the terminal output:

$> 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 =========================

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)

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


回答1:


It is a back-tick in

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

that trips the parser.

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.



来源:https://stackoverflow.com/questions/17376475/antlr-grammar-for-scheme-r5rs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!