问题
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