[英]ANTLR grammar for scheme R5RS
I'm beginner in ANTLR and I'm learning it by an example. 我是ANTLR的初学者,并且通过示例进行学习。 I use C as my target language.
我使用C作为目标语言。 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).
该示例是从该问题中提取的Scheme R5RS语法文件,进行了一些修改(重命名语法名称,并添加一些未更改语法规范的选项)。
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. antlr生成了词法分析器和解析器,然后使用测试
main()
对其进行编译,在其中我进行了一些初始化并仅调用了解析器。 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 test.c中的
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;
}
scheme code in test.scm: 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. 按照
pattern
和template
的语法规则,我转到下面的代码片段。 I think the parse is going to match template
with it and failed because template
doesn't have an quasiquote
alternative. 我认为解析将使
template
与之匹配,但失败了,因为template
没有quasiquote
替代方案。
`("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). 我相信
template
的语法规则正确地遵循了R5RS规范,并且该代码被其他R5Rs方案实现接受(我在scheme48和guile中对其进行了测试)。 How can this happen? 怎么会这样
I think there must be something wrong in my analyse ... 我认为我的分析中肯定有问题...
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. 如果您遵循模式和模板的语法规则,则会看到它们没有达到与
QUASIQUOTE
和反勾号都匹配的QUASIQUOTE
quasiquotation
规则。 They do however reach expressionKeyword
that contains QUASIQUOTE
. 然而,他们也达到
expressionKeyword
包含QUASIQUOTE
。
You should fix grammar to include abbreviated forms in template or fix your input not to use them. 您应该修复语法以在模板中包含缩写形式,或者修复输入内容以免使用它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.