Những câu trả lời khác đề nghị sửa đổi các văn phạm, điều này không thể thực hiện được khi chơi với C++ ngữ pháp (vài trăm quy tắc ..)
May mắn thay, chúng ta có thể làm điều đó tự động, bằng cách xác định lại debug macro. Trong mã này, chúng tôi đang đánh giá lại YY_SYMBOL_PRINT
actived với YYDEBUG
:
%{
typedef struct tree_t {
struct tree_t **links;
int nb_links;
char* type; // the grammar rule
};
#define YYDEBUG 1
//int yydebug = 1;
tree_t *_C_treeRoot;
%}
%union tree_t
%start program
%token IDENTIFIER
%token CONSTANT
%left '+' '-'
%left '*' '/'
%right '^'
%%
progam: exprs { _C_treeRoot = &$1.t; }
|
| hack
;
exprs:
expr ';'
| exprs expr ';'
;
number:
IDENTIFIER
| '-' IDENTIFIER
| CONSTANT
| '-' CONSTANT
;
expr:
number
| '(' expr ')'
| expr '+' expr
| expr '-' expr
| expr '*' expr
| expr '/' expr
| expr '^' expr
;
hack:
{
// called at each reduction in YYDEBUG mode
#undef YY_SYMBOL_PRINT
#define YY_SYMBOL_PRINT(A,B,C,D) \
do { \
int n = yyr2[yyn]; \
int i; \
yyval.t.nb_links = n; \
yyval.t.links = malloc(sizeof *yyval.t.links * yyval.t.nb_links);\
yyval.t.str = NULL; \
yyval.t.type = yytname[yyr1[yyn]]; \
for (i = 0; i < n; i++) { \
yyval.t.links[i] = malloc(sizeof (YYSTYPE)); \
memcpy(yyval.t.links[i], &yyvsp[(i + 1) - n], sizeof(YYSTYPE)); \
} \
} while (0)
}
;
%%
#include "lexer.c"
int yyerror(char *s) {
printf("ERROR : %s [ligne %d]\n",s, num_ligne);
return 0;
}
int doParse(char *buffer)
{
mon_yybuffer = buffer;
tmp_buffer_ptr = buffer;
tree_t *_C_treeRoot = NULL;
num_ligne = 1;
mon_yyptr = 0;
int ret = !yyparse();
/////////****
here access and print the tree from _C_treeRoot
***///////////
}
char *tokenStrings[300] = {NULL};
char *charTokenStrings[512];
void initYaccTokenStrings()
{
int k;
for (k = 0; k < 256; k++)
{
charTokenStrings[2*k] = (char)k;
charTokenStrings[2*k+1] = 0;
tokenStrings[k] = &charTokenStrings[2*k];
}
tokenStrings[CONSTANT] = "CONSTANT";
tokenStrings[IDENTIFIER] = "IDENTIFIER";
extern char space_string[256];
for (k = 0; k < 256; k++)
{
space_string[k] = ' ';
}
}
các lá được tạo ra ngay trước khi RETURN trong lexer FLEX
Cảm ơn, tôi đã nhìn thấy điều này trước đây trong các Lexx & yacc cuốn sách. Nhưng tôi đã viết nó như một cái chết. Để làm cho mọi thứ được treo lại với nhau, bạn cần sửa đổi LexType được xác định trong thẻ union % union { Trạng thái riêng tư _state; ... LexValue (Trạng thái nhà nước, đối tượng child1, đối tượng child2) {...} } Điều này cho phép bạn lưu trữ một nút cây làm trạng thái của bạn. Sau đó, bạn có thể chỉ định dữ liệu cho nó bằng cách sử dụng $$ alias $$ = new LexValue (State.SchemaImport, $ 3, $ 5); Lưu ý: Từ khóa cũng cần đẩy dữ liệu mã thông báo của nó vào cấu trúc này. Dễ dàng khi bạn biết cách ... – Sprotty