Вот небольшая демонстрация, как использовать сгенерированный (C) синтаксический анализатор ANTLR для компиляции и запуска, используя make
:
Вам нужны следующие 4 файла:
T.g
grammar T;
options {
language=C;
}
parse
: (t=. {printf("token: '\%s'\n", $t.text->chars);})+ EOF
;
NUMBER
: ('0'..'9')+ ('.' ('0'..'9')+)?
;
WORD
: ('a'..'z' | 'A'..'Z')+
;
OTHER
: .
;
input.txt
foo 42 BAR 3.141592
main.c
#include "TLexer.h"
#include "TParser.h"
int main(int argc, char *argv[])
{
pANTLR3_UINT8 fileName = (pANTLR3_UINT8)"input.txt";
pANTLR3_INPUT_STREAM input = antlr3AsciiFileStreamNew(fileName);
if(input == NULL)
{
fprintf(stderr, "Failed to open file %s\n", (char *)fileName);
exit(1);
}
pTLexer lexer = TLexerNew(input);
if(lexer == NULL)
{
fprintf(stderr, "Unable to create the lexer due to malloc() failure1\n");
exit(1);
}
pANTLR3_COMMON_TOKEN_STREAM tstream = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lexer));
if(tstream == NULL)
{
fprintf(stderr, "Out of memory trying to allocate token stream\n");
exit(1);
}
pTParser parser = TParserNew(tstream);
if(parser == NULL)
{
fprintf(stderr, "Out of memory trying to allocate parser\n");
exit(ANTLR3_ERR_NOMEM);
}
parser->parse(parser);
parser->free(parser); parser = NULL;
tstream->free(tstream); tstream = NULL;
lexer->free(lexer); lexer = NULL;
input->close(input); input = NULL;
return 0;
}
Makefile
run: T.g main.c
java -cp antlr-3.3.jar org.antlr.Tool T.g
gcc -Wall main.c TLexer.c TParser.c -l antlr3c -o main
./main
Если вы сейчас запустите make
, будет напечатано следующее (по крайней мере, на моей Ubuntu-коробке):
token: 'foo'
token: ' '
token: '42'
token: ' '
token: 'BAR'
token: ' '
token: '3.141592'
token: '
'
Излишне говорить, что antlr-3.3.jar
должен находиться в том же каталоге, что и другие файлы .g и .c, а компилятор C должен найти antlr3c
в вашей системе.
Кроме того, при копировании Makefile
обязательно сохраняйте отступы в начале строк.