【问题标题】:compiling a file using an ANTLR grammar使用 ANTLR 语法编译文件
【发布时间】:2012-03-07 18:44:27
【问题描述】:

我一直在编写 antlr 语法,最终将用作 smallC 程序编译器的一部分。为了提取代码,我最初使用的是调用语法并包含输入字符串(smallC 代码)的 java 程序,这已经奏效了。

不幸的是,我刚刚被告知我们必须使用可以调用语法和 .c smallC 程序并生成 .exe 的 makefile 来执行此操作。截止日期很快,我只是想知道这有多大可能,如果有人对此有任何建议,我之前还没有真正使用过 makefile。

谢谢。

【问题讨论】:

  • 你在这里问什么问题?我不清楚你需要什么帮助。
  • 好吧,我什至不知道从哪里开始,您知道编写适用于 java 和 antlr 的 makefile 的任何好的教程或参考资料吗?
  • 您能更详细地描述所需的工作流程吗?假设我有一个新的 SmallC 程序。在你的世界里我该怎么处理它才能让它运行?
  • 对不起,我在这里的描述有点垃圾。谢谢你的耐心。好的,所以我有我的 antlr 文件,.g 语法,其中定义了我的所有解析器/词法分析器规则等。我还有一个 java 文件,它当前需要一个输入字符串并输出树(尽管我希望修改它以从 .c 文件中提取文本),我想创建一个运行它的 makefile,或者制作一个可执行文件会的。
  • Makefile 对 ANTLR 帮助不大。相反,我想您需要使用Bison 语法解析器(另请参阅wiki)。所以你的Makefile 可能看起来像上面提到的here

标签: java makefile antlr


【解决方案1】:

这是一个小演示,如何使用 ANTLR 生成的 (C) 解析器使用 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
  :  .
  ;

输入.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;
}

生成文件

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-box 上):

token: 'foo'
token: ' '
token: '42'
token: ' '
token: 'BAR'
token: ' '
token: '3.141592'
token: '
'

不用说,antlr-3.3.jar 需要与其他 .g 和 .c 文件位于同一目录中,并且 C 编译器需要在您的系统上找到 antlr3c

另外,在复制粘贴 Makefile 时,请务必保留行首的缩进制表符。

【讨论】:

  • 没想到ANTLR可以produce C targets ;) +1
  • @dma_k,是的,ANTLR 可以为很多目标生成解析器(参见:antlr.org/wiki/display/ANTLR3/Code+Generation+Targets)。并不是所有的都一样好,但其中不少是(其中之一是 C 目标)。
  • 这真的很有帮助,非常感谢。我已将您的答案标记为正确答案,希望它能指导那些后代为奇怪的程序创建 makefile。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多