野牛 - 如何打印解析树(Bison - how to print a parse tree)

2019-07-29 01:58发布

你好我工作的一个小野牛,以了解它是如何工作的。 野牛应该分析句子。 这句话是由表达式和表达式是由单词的。

以下是我的代码:

%{
#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;
    }
    ;

所以,当用户输入一个单词,它应该打印出来的字。 用户应该能够输入:字,词字,字和字

我不知道如何使用,必须通过文字$$并从“查询表达式”的规则打印出来。 我该怎么做呢?

这是我的Flex:

%{
#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 */;

%%

在此先感谢这么多。 莎拉

Answer 1:

通常情况下,写一个解析器的目标是让你最终表示输入的数据结构。 然后,变换的结构以某种方式,或者,你的情况,只是把它打印出来。

在每个表达产物,要建立在结构中的节点,它表示,到目前为止,你已经认识到了什么。

我有点生疏,但它会是这样的:

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

请注意,您的文字标记只是表示的某种字母串进行扫描; 字母的特定序列被丢弃。 (如果你想知道的序列,有你的词法分析器返回yytext中,而不是文字标记的副本。)

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

且同样makeOrNode()。 或者,你可以写只是makeNodeWithOperator(INT操作,结构节点* leftOperand,结构节点* rightOperand)处理“与”和“或”案件。

我改变printAllNodes()来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;
    }
}


文章来源: Bison - how to print a parse tree
标签: bison