2012-04-20 7 views
2

こんにちは私はそれがどのように動作するかを知るために小さなバイソンに取り組んでいます。バイソンは文章を解析することになっています。 文は式で構成され、式は単語で構成されます。続きBison - 構文解析ツリーの印刷方法

は私のコードです:だから

%{ 
#include <stdio.h> 
#include <string.h> 


void yyerror(const char *str) 
{ 
    fprintf(stderr,"error: %s\n",str); 
} 

int yywrap() 
{ 
    return 1; 
} 

main() 
{ 
    yyparse(); 
} 

%} 

%token ASSIGN RANGE OR AND WHITESPACE QUOTE LPAREN RPAREN NOT GREATER LESS 

%union 
{ 
     int number; 
     char *string; 
} 

%token <number> VALUE 
%token <string> WORD 

%type <string> term 
%type <string> expression 
%% 

query: /* empty */ 
    | query expression 
    { 
     printf("WOrd:%s",$2); 
    } 
    ; 

expression: 
    term 
    |expression term 
    |expression AND term 
     { 
      printf("AND"); 
     } 
    ; 

term: 
    WORD 
    { 
     $$=$1; 
    } 
    ; 

、ユーザーが単語を入力したとき、それは言葉をプリントアウトすることになって。 ユーザーは入力できる必要があります: 単語、単語、単語、単語

$$を使用して単語を渡して「クエリ式」ルールから出力する方法はわかりません。 どうすればよいですか?事前に

%{ 
#include <stdio.h> 
#include <string.h> 
#include "y.tab.h" 
%} 
%% 
[0-9]+     yylval.number=atoi(yytext);return VALUE; 
[a-zA-Z][a-zA-Z]*  yylval.string=strdup(yytext);return WORD; 
":"      return ASSIGN; 
"and"|"&"|"&&"   return AND; 
".."     return RANGE; 
"-"      return NOT; 
"|"      return OR; 
"\""     return QUOTE; 
">"      return GREATER; 
"<"      return LESS; 
\n      /* ignore end of line */; 
\t      /* ignore end of line */; 

%% 

本当にありがとうございました:

は、これが私のフレックスです。 Sarah

答えて

6

通常、パーサの作成のポイントは、入力を表すデータ構造になるためです。次に、構造を何らかの方法で変換するか、場合によっては、それを印刷します。

各式の作成では、これまでに認識したものを表す構造体のノードを作成する必要があります。

私は少しさびたんだけど、このようなものになるだろう:

query: /* empty */ 
    | query expression { printNode($2); /* printf()s are in here */ } 
; 

expression: term { $$ = makeTermNode($1); } 
      | expression OR term { $$ = makeOrNode($1, $3); } 
      | expression AND term { $$ = makeAndNode($1, $3); } 
; 

データ構造、あなたのノードを保持する:

struct Node { 
    int nodeType;   /* WORD or operator token like AND, OR */ 
    node* leftOperand; 
    node* rightOperand; /* will be null if the node is a term */ 
} 

%union 
{ 
    int number; 
    char *string; 
    Node *node; 
} 

アップデート:

にです私はC言語でコード化してからしばらくしていたので、私は擬似コードに頼らなければなりません。いったん完了したらメモリを再利用するコードはありません。他の失業者のための謝罪。

struct Node *makeTermNode(int word) { 
    Node *node = malloc(sizeof struct Node); 
    node->nodeType = word; 
    node->rightOperand = null; 
    node->leftOperand = null; 
    return node; 
} 

WORDトークンは、ある種の文字列がスキャンされたことを示しています。特定の文字列は破棄されます。 (あなたはシーケンスを知りたい場合は、あなたのレクサーではなくWORDトークンのyytextのコピーを返しています。)makeOrNodeため

struct Node *makeAndNode(struct Node* leftOperand, struct Node *rightOperand) { 
    Node *node = malloc(sizeof struct Node); 
    node->nodeType = AND; 
    node->leftOperand = leftOperand; 
    node->rightOperand = rightOperand; 
    return node; 
} 

と同様に()。代わりに、 "and"と "or"の場合を処理するためにmakeNodeWithOperator(int演算子、struct Node * leftOperand、struct Node * rightOperand)と書くこともできます。

printNode()をprintNode()に変更しました。これは、構築した式ツリー構造のルートから始まり、最初に各部分式の左側を再帰的に参照し、次に右側に移動します。

void printNode (struct Node* node) { 
    switch (node->nodeType) { 
    case WORD: 
     printf("%i", node->nodeType); 
     return; 
    case AND: 
    case OR: 
     printf("("); 
     printNode(node->leftOperand); 
     printf("%i", node->nodeType); 
     printfNode(node->rightOperand); 
     printf(")"); 
     return; 
    } 
} 
+0

あなたが言及した関数のコードを提供してくださいすることができます:printALlNodes、makeTermNode、makeORNode ...本当にありがとうございました – sap

+0

はちょうど私があなたの説明と簡単な例を認めることを言いたかったことは、このようなものになります。ジェネリックフォーマル言語とパースアルゴリズムの複雑な例を見てみるといいですね。 – mouche

関連する問題