2011-07-09 36 views
5

Đây không phải là bản sao của this question vì giải pháp không sử dụng trình phân tích cú pháp!Kết hợp Trình phân tích cú pháp Yacc/Bison với chương trình C++

Tôi có trình phân tích cú pháp Bison mà tôi có thể chạy bằng cách thực hiện ./parser < file_to_parse. Tôi muốn gọi trình phân tích cú pháp Bison từ bên trong chương trình C++ của tôi. Những gì tôi không muốn là làm system(./parser < file_to_parse) vì điều đó sẽ cho rằng trình phân tích cú pháp được biên dịch trước và sau đó toàn bộ chương trình của tôi sẽ không là nền độc lập.

Nếu tôi có một chức năng:

void foo(file_name) { 
    // call parser on file_name 
} 

thì cách này có thể thực hiện? Bất kỳ ý tưởng? Tôi nghĩ rằng đó là trường hợp gọi yyparse hoặc một cái gì đó nhưng tôi không nhận được bất cứ nơi nào với nó!

Cảm ơn bạn :).

Trả lời

1

Đó chính xác là những gì bạn làm - bạn gọi yyparse(). Bạn viết yylex() sao cho chương trình chính của bạn có thể xác định đầu vào của nó. Có lẽ yylex hiện tại của bạn() gọi getchar() hoặc một cái gì đó để đọc một nhân vật; thay vào đó bạn có thể cần phải viết nó để lấy đầu vào từ một số nơi được chỉ định bởi chương trình chính của bạn.

+0

Cảm ơn Ernest .. vẫn đang vật lộn nhưng hy vọng tôi sẽ đến đó. Tôi không thực sự có một yylex() trong lexer của tôi - Flex tạo ra một mặc định một trong đó có thể làm các getchar(). Tôi đoán tôi cần phải viết của riêng tôi trong lexer hoặc một cái gì đó. – ale

2

Bạn đang sử dụng phiên bản thích hợp với C++?

Tôi sử dụng cái của Alain Coetmeur.

Hiện tại, tôi chỉ có mã để sử dụng flex ++, nhưng nó sẽ cho bạn biết cách này đi.

Khi bạn chạy flex ++, nó sẽ xuất ra tệp tiêu đề và tệp triển khai cho lớp mới để thực hiện phân tích cú pháp. Hãy thêm những dự án này vào dự án của bạn, sau đó viết:

// Construct new instance of parser 
::lex * plex = new lex(); 

// tell parser what file to parse 
plex->yyin = _wfopen(L"C:/Documents and Settings/All Users/Application Data/QuietWake/eCrew/new_rules_to_be_parsed.txt",L"r"); 

// run the parser 
int lex_return = plex->yylex(); 
+0

Cảm ơn bạn. Tôi đang thực sự sử dụng Flex/Bison cũ .. Tôi chỉ nhận thức được có C + + ngày hôm qua! .. Chắc chắn sẽ có được tốt hơn để sử dụng một trong những bạn đang sử dụng. Tôi sẽ thử và giải quyết nó bằng cách sử dụng các công cụ của tôi và nếu nó không thành công thì tôi sẽ xem xét các C++ này. Cảm ơn bạn +1. – ale

+0

Tôi khuyên bạn nên thực hiện thay đổi ngay bây giờ. Các trình phân tích cú pháp mới tương thích với cũ, vì vậy bạn sẽ không mất bất kỳ khoản đầu tư nào trong quá trình viết kịch bản. Và cuộc sống sẽ dễ dàng hơn nhiều. – ravenspoint

+0

Tôi bị kẹt vì vậy tôi sẽ làm điều đó :). Sẽ đánh dấu là giải pháp nếu nó hoạt động. Cảm ơn bạn. – ale

1

Đây là mã C nhưng tôi đoán nó cũng là một trường hợp chỉ định cho C++.
Khi chúng tôi đã có để thực hiện một trình biên dịch trong các trường đại học chúng tôi phải xác định YY_DECL trong một file .l như thế này:

 
#define YY_DECL int alpha_yylex(yylval_) void *yylval_; 

Các int alpha_yylex(yylval_) là chức năng và void *yylval là kiểu tham số.
Rõ ràng, bạn cần điều này để cho trình phân tích cú pháp biết nơi bắt đầu từ aka chức năng nào là phân tích cú pháp nên được thực hiện từ đó.

Bạn cũng cần phải xuất bản mẫu chức năng này (extern int alpha_yylex(void *yylval_);) trong tệp .y của mình.
Sau đó, tiện ích Flex/Bison sẽ tự động phát các tệp .c có liên quan cho bạn.

Nói chung, .l là dành cho các quy tắc từ vựng và .y là dành cho các quy tắc ngữ pháp. Vì vậy nếu bạn cần để có được giá trị từ một nơi nào bạn phải xác định một đoàn trong .y như thế này (ví dụ):

%union { 

    union { 
     int Integer; 
     double Double; 
     char Character; 
     char* String; 
    } value; 

} 

Sau đó, tùy thuộc vào quy tắc cú pháp và bạn, bạn có thể làm yylval.value.String = strdup(yytext) trong .l file của bạn và, tùy thuộc vào các quy tắc ngữ pháp của bạn, $$.Double = $1.Double + $3.Double trong tệp .y của bạn.

Tôi không nhớ rất nhiều kể từ khi nó được một lúc mà tôi đã làm điều đó nhưng tôi đoán bạn có thể thử và bạn có thể tham khảo tài liệu hoặc yêu cầu ở đây :)

PS: (Tôi đã có một Câu hỏi thường gặp ở đâu đó nhưng không thể nhớ nó ở đâu -> sẽ đăng sau nếu tôi may mắn tìm thấy nó xD: D xD)

Các vấn đề liên quan