yacc 不打印 AST

yacc do not printing AST

编辑我的问题。 在表达式规则中:exp 不会减少到 expression 例如:标识符(exp)-标识符(exp)

运行 测试:http://www.interload.co.il/upload/2528784.png 在图像中,您可以看到 yacc 出于某种原因正在等待更多输入。 表达式规则有什么问题? --------------------------yacc代码-------------------- ------------

          %{
            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            typedef struct node
            {
                    char* token;
                    struct node* left;
                    struct node* right;
            }node;
            node* mknode(char* token,node* left, node* right);
            void printtree(node* tree);
            #define YYSTYPE struct node*
    %}
    %start s
    %token WHILELOOP
    %token STATIF
    %token ELSE
    %token MAIN
    %token POINTERERR
    %token COMMENT
    %token POINTER
    %token GREATEREQUAL
    %token LESSEREQUAL
    %token DBLAND
    %token GREATER
    %token LESSER
    %token LESSER
    %token POWER
    %token MULTIPLY
    %token MINUS
    %token PLUS
    %token AND
    %token OR
    %token NOT
    %token NOTEQUAL
    %token CHARERROR
    %token STRINGERROR
    %token POINTER
    %token INTEGER
    %token BOOLEAN
    %token DEVIDE
    %token ASSIGN
    %token EQUAL
    %token TYPE
    %token IDENTIFIER
    %token HEX IF
    %token LITERCHAR
    %token OCTAL
    %token BINARYINT
    %token LTRLSTRING
    %token COMMA COLON SEMICOLON VAR RETURN RPARENC LPARENC
    %left COMMA LPAREN RPAREN
    %left PLUS
    %left MINUS DEVIDE
    %left MULTIPLY EQUAL NOTEQUAL OR AND LESSEREQUAL GREATEREQUAL GREATER LESSER
    %right IDENTIFIER
    %%
    s: expression|operator|var_declare|if_stnt;
    {
            printf("blaAA bla/n");
    };
    expression: exp {printtree();}
    exp: exp PLUS exp {$$=mknode("+",,);}
                    |exp MINUS exp {$$=mknode("-",,);}
                    |exp DEVIDE exp {$$=mknode("/",,);}
                    |exp MULTIPLY exp {$$=mknode("*",,);}
                   | MINUS exp {$$=mknode("-",NULL,);}
                    |IDENTIFIER {$$= mknode(yytext,NULL,NULL);}

    operator: op{printtree();}
              op: exp EQUAL exp {$$=mknode("=",,);}
                    |exp NOTEQUAL exp {$$=mknode("!=",,);}
                    |exp OR exp {$$=mknode("||",,);}
                    |exp AND exp {$$=mknode("&&",,);}
                    |exp GREATER exp {$$=mknode(">",,);}
                    |exp GREATEREQUAL exp {$$=mknode(">=",,);}
                    |exp LESSER exp {$$=mknode("<",,);}
                    |exp LESSEREQUAL exp {$$=mknode("<=",,);}

var_declare: var {printtree();}
             var: VAR ident_list COLON TYPE SEMICOLON{$$=mknode("var",,);}



    ident_list: ident_list COMMA ident_list {$$=mknode(",", , );}
              |IDENTIFIER {$$= mknode(yytext,NULL,NULL);}

    if_stnt:IF LPAREN exp RPAREN
    %%
    #include "lex.yy.c"
    main()
    {
            return yyparse();
    }
    node* mknode(char* token,node*left,node* right)
    {
            node* newnode=(node*)malloc(sizeof(node));
            char* newstr=(char*)malloc(sizeof(token)+1);
            newstr[sizeof(token)]='[=10=]';
            strcpy(newstr,token);
            newnode->left=left;
            newnode->right=right;
            newnode->token=newstr;
            return newnode;
    }
    void printtree(node* tree)
    {

            printf("%s\n",tree->token);
            if(tree->left)printtree(tree->left);
            if(tree->right)printtree(tree->right);
    }
    int yyerror()
    {
            printf("bla bla\n");
            return 0;
            }

----------------词法代码:------------------------ -----

minus "-"
colon ":"
semicolon ";"
space " "
parcent "%"
backslash "/"
charptr charptr
plus "+"
not "!"
notequal "!="
or "||"
and "&&"
multiply "*"
power "^"
dbland "&"
greater ">"
lesser "<"
return "return"
greaterequal {greater}{assign}
lesserequal {lesser}{assign}
singleQuotes \'
charERR {singleQuotes}+(({digit})+)*(({letter})+)*{singleQuotes}+
stringERR {doubleQuotes}{doubleQuotes}+|{doubleQuotes}
doubleQuotes \"
octalDigit [1-7]
decimal {digit}|{digitNoZero}{digit}+
digitNoZero[1-9]
octal "0"{octalDigit}("0")*{octalDigit}*
integer {binaryInt}|{hex}|{octal}|{decimal}
binaryInt ("0"|"1")+"b"
hexLetter A|B|C|D|E|F
hex 0(x|X){digit}+{hexLetter}*|0(x|X){digit}*{hexLetter}+
literBool true|false
letter [a-zA-Z]
letters {letter}+
digit [0-9]
low "_"
equal "=="
assign "="
devide "/"
lparen "("
rparen ")"
lparenc "{"
rparenc "}"
identifier {letter}+{digit}*{letter}+|{letter}
type boolean|string|char|integer|intptr|charptr|var
literChar {singleQuotes}{letter}{singleQuotes}
ltrlString {doubleQuotes}{letters}*{decimal}*{hex}*{octal}*{binaryInt}*{dbland}*$
pointer {colon}{space}{charptr}|"="{space}"&"{identifier}
comment {backslash}{parcent}{space}*({letters}*{space}*{identifier}*{space}*{dec$
pointerErr "&"{identifier}|{charptr}
statif "if"{space}*
ELSE "else"{space}*
comma ","
whileLoop "while"{space}*
main "main"
var "VAR"
%%
{lparen} return LPAREN;
{rparen} return RPAREN;
{colon} return COLON;
{semicolon} return SEMICOLON;
{var} return VAR;
{whileLoop} return WHILELOOP;
{ELSE} return ELSE;
{statif} return IF;
{pointerErr} return POINTERERR;
{comment} return COMMENT;
{pointer} return POINTER;
{literChar} return LITERCHAR;
{charERR} return CHARERROR;
{stringERR} return STRINGERROR;
{ltrlString} return LTRLSTRING;
{binaryInt} return BINARYINT;
{octal} return OCTAL;
{hex} return HEX;
{return} return RETURN;
{greaterequal} return GREATEREQUAL;
{lesserequal} return LESSEREQUAL;
{dbland} return DBLAND;
{greater} return GREATER;
{lesser} return LESSER;
{lparenc} return LPARENC;
{rparenc} return RPARENC;
{power} return POWER;
{multiply} return MULTIPLY;
{plus} return PLUS;
{or} return OR;
{and} return AND;
{comma} return COMMA;
{not} return NOT;
{main} return MAIN;
{notequal} return NOTEQUAL;
{minus} return MINUS;
{integer} return INTEGER;
{literBool} return BOOLEAN;
{identifier} return IDENTIFIER;
{equal} return EQUAL;
{assign} return ASSIGN;
{devide} return DEVIDE;
{type} return TYPE;
. return yytext[0];

为了做最后的缩减s: expression和return,yacc需要在输入的末尾看到EOF。如果您正在从文件中读取,那么 EOF 会自动出现,但是终端输入没有 end,因此对于来自终端的输入,您需要给它一个显式的通过点击 ctrlDctrlZ 来指示 EOF windows).