是否有可能使YACC(或我是我的案例MPPG)輸出抽象語法樹(AST)。使YACC輸出一個AST(令牌樹)
我正在閱讀的所有東西都表明它很容易讓YACC做到這一點,但我很努力想知道如何知道在構建它時如何在樹中移動節點。
是否有可能使YACC(或我是我的案例MPPG)輸出抽象語法樹(AST)。使YACC輸出一個AST(令牌樹)
我正在閱讀的所有東西都表明它很容易讓YACC做到這一點,但我很努力想知道如何知道在構建它時如何在樹中移動節點。
你看過the manual(搜索「解析樹」來找到該點)?它建議將節點創建放在一個動作中,左右後裔的價格分別爲1美元和3美元,或者任何可能的情況。在這種情況下,yacc會代表您以樹的形式向上移動,而不是手動進行。
擴大對郝的觀點,並從the manual,你想要做的東西像下面這樣:
假設你有一個功能node
您的抽象語法樹,會在樹中的對象:
expr : expr '+' expr
{
$$ = node('+', $1, $3);
}
這段代碼翻譯爲「當用一個加號解析表達式時,取左邊和右邊的後代$1
/$3
並將它們用作節點的參數。將表達式的輸出保存到$$
(返回值)。
$$(從手動):
返回一個值,該動作通常 設置pseudovariable``$$ '' 一些 值。
其他的答案建議修改語法與C++語法(規則幾百..)
幸運玩的時候,這是不可行的,我們可以自動做到這一點,通過重新定義調試宏。 在這段代碼中,我們將重新定義YY_SYMBOL_PRINT
與YYDEBUG
actived:
%{
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] = ' ';
}
}
的葉子剛剛在FLEX詞法分析器
謝謝你,我會在lexx&YACC書見過這個在返回之前被創建。但我會把它寫成死衚衕。 爲了讓它全部掛在一起,你需要修改聯合標記中定義的LexType %union private_state; ... LexValue(狀態,對象child1,對象child2){...} } 這允許您將樹節點存儲爲您的狀態。 然後,您可以使用$$別名 $$ = new LexValue(State.SchemaImport,$ 3,$ 5)將數據分配給它。 注意:詞法分析器還需要將其令牌數據推送到此結構中。 簡單,當你知道如何... – Sprotty 2009-06-04 19:17:04