รวบรวมไฟล์โดยใช้ไวยากรณ์ ANTLR

ฉันได้เขียนไวยากรณ์ antlr เพื่อนำไปใช้เป็นส่วนหนึ่งของคอมไพเลอร์สำหรับโปรแกรม SmallC ในที่สุด สำหรับการดึงโค้ด เดิมทีฉันใช้โปรแกรมจาวาซึ่งเรียกไวยากรณ์และมีสตริงอินพุต (โค้ด smallC) และสิ่งนี้ก็ใช้งานได้

น่าเสียดายที่ฉันเพิ่งได้รับแจ้งว่าเราต้องทำสิ่งนี้โดยใช้ makefile ที่สามารถเรียกใช้ไวยากรณ์และโปรแกรม .c smallC และสร้าง .exe กำหนดเวลาสำหรับเรื่องนี้คือเร็วๆ นี้ และฉันแค่สงสัยว่าเป็นไปได้อย่างไร และถ้าใครมีคำแนะนำในการดำเนินการนี้ ฉันยังไม่เคยทำงานกับ makefiles มาก่อนเลย

ขอบคุณ.


person djcmm476    schedule 16.02.2012    source แหล่งที่มา
comment
คุณถามคำถามอะไรที่นี่? ฉันไม่ชัดเจนว่าคุณต้องการความช่วยเหลือในเรื่องใด   -  person kittylyst    schedule 16.02.2012
comment
ยิ่งไปกว่านั้น ฉันไม่แน่ใจด้วยซ้ำว่าจะเริ่มต้นจากตรงไหน คุณรู้จักบทช่วยสอนดีๆ หรือเอกสารอ้างอิงสำหรับการเขียน makefiles ที่ทำงานกับ java และ antlr ได้ไหม   -  person djcmm476    schedule 16.02.2012
comment
คุณช่วยอธิบายขั้นตอนการทำงานที่ต้องการโดยละเอียดได้ไหม สมมติว่าฉันมีโปรแกรม SmallC ใหม่ ฉันจะทำอย่างไรกับมันในโลกของคุณเพื่อให้มันทำงานได้?   -  person kittylyst    schedule 16.02.2012
comment
ขออภัย ฉันค่อนข้างขยะแขยงกับคำอธิบายของฉันที่นี่ ขอบคุณที่อดทน ตกลง ฉันมีไฟล์ antlr ซึ่งเป็นไวยากรณ์ .g ที่ใช้กำหนดกฎ parser/ lexer ฯลฯ ทั้งหมด ฉันยังมีไฟล์จาวาที่ปัจจุบันใช้สตริงอินพุตและส่งออกทรี (แม้ว่าฉันหวังว่าจะแก้ไขมันเพื่อดึงข้อความออกจากไฟล์ .c) และฉันต้องการสร้าง makefile ที่จะเรียกใช้สิ่งนี้หรือสร้างไฟล์ปฏิบัติการได้ นั่นจะ.   -  person djcmm476    schedule 16.02.2012
comment
Makefile จะไม่ช่วยคุณมากกับ ANTLR ฉันคิดว่าคุณต้องใช้ Bison ตัวแยกวิเคราะห์ไวยากรณ์ (ดูเพิ่มเติมใน wiki) ดังนั้น Makefile ของคุณอาจดูเหมือนมีคนพูดถึงที่นี่   -  person dma_k    schedule 17.02.2012


คำตอบ (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
  :  .
  ;

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

เมคไฟล์

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 อย่าลืมคงแท็บที่เยื้องไว้ที่จุดเริ่มต้นของบรรทัด

person Bart Kiers    schedule 17.02.2012
comment
ฉันไม่คิดว่า ANTLR สามารถ สร้างเป้าหมาย C ;) +1 - person dma_k; 18.02.2012
comment
@dma_k ใช่แล้ว มีเป้าหมายค่อนข้างน้อยที่ ANTLR สามารถสร้าง parser ได้ (ดู: antlr.org/wiki/display/ANTLR3/Code+Generation+Targets ) ไม่ใช่ทั้งหมดจะดีเท่ากัน แต่มีบางส่วนที่ดีเท่ากัน (หนึ่งในนั้นคือเป้าหมาย C) - person Bart Kiers; 18.02.2012
comment
นั่นมีประโยชน์จริงๆ ขอบคุณมาก ฉันได้ทำเครื่องหมายคำตอบของคุณว่าถูกต้องแล้ว มันอาจจะแนะนำคนรุ่นต่อไปในการสร้าง makefiles สำหรับโปรแกรมแปลก ๆ - person djcmm476; 24.02.2012