c - lex/yacc 项目编译时出现问题

标签 c bison yacc lex

我正在使用 lex 和 yacc 开发编译器。我遇到了编译错误,我相信如果我能解决其中一项,其余的就会水到渠成。我这样编译项目:

gcc -ll *.c -o <program_name>

我具体讨论的错误如下:

In file included from scanner.lex:11:
y.tab.h:6: error: syntax error before "tree"
y.tab.h:6: warning: no semicolon at end of struct or union
y.tab.h:6: error: syntax error before '}' token
y.tab.h:6: warning: data definition has no type or storage class
y.tab.h:7: error: syntax error before "yylval"
y.tab.h:7: warning: data definition has no type or storage class
scanner.lex: In function `yylex':
scanner.lex:55: error: request for member `i' in something not a structure or union
scanner.lex:56: error: request for member `i' in something not a structure or union
scanner.lex:57: error: request for member `f' in something not a structure or union

我根本看不出这个结构有什么问题。我希望有人能指出我们的错误并建议更正。如果有必要,我会发布更多代码。我使用的是 yacc 和 lex,而不是 flex 或 bison。至于版本,我不能告诉你。 GCC 版本为 3.4.5

我讨厌这样做,但根据请求我添加了完整的代码。抱歉,我真的无法将其“配对”到可编译版本。

yacc 文件:

%{

#include "tree.h"

extern tree root;


%}

%token <i> Ident 1 IntConst 2
%token <f> RealConst 3 
%token     And 4 Array 5
%token <i> Begin 6 
%token     Boolean 7 Div 8 Do 9 Else 10
%token     End 11 False 12 For 13 Goto 14 If 15
%token     Imply 16 Integer 17 Label 18 Not 19 Or 20
%token     Own 21 Procedure 22 Real 23 Step 24 String 25
%token     Then 26 True 27 Until 28 Value 29 While 30
%token     Plus 31 Minus 32 Mult 33 Divide 34 Less 35
%token     LessEq 36 Great 37 GreatEq 38 Eq 39 NotEq 40
%token     Comma 41 Colon 42 Semi 43 LParan 44 RParan 45
%token     LBrak 46 RBrak 47 Assign 48 

%start program

%union { tree t; int i; float f; }

%type <t>       program block optdecls decl vardecl type idlist arraydecl arraylist arrayseg
%type <t>       stmts stmt u_stmt assign dummy for_stmt if_stmt var factor term sum
%type <t>       brel relation bsecond bfactor bterm expr a_expr

%%

program 
    : block
            { root = $1; }
    ;

block
    : Begin optdecls stmts End
            { $$  = buildTree(Begin, $2, $3, buildTree(End,NULL, NULL,NULL)); }
    ;

optdecls
    : /* empty */
            { $$ = NULL; }
    | decl Semi optdecls
            { $$ = buildTree(Semi, $1, $3, NULL); }
            /*{$$ = buildTree(Semicol,$1, NULL, NULL);$$->next = $3;} */
    ;

decl    
    : vardecl
            { $$ = $1; }
    | arraydecl
            { $$ = $1; }
    ;

vardecl
    : type idlist
            { $$->next = $2; $$ = $1; } 
    ;

type
    : Real
            { $$ = buildFloatTree(Real, $<f>1); }
    | Integer
            { $$ = buildIntTree(Integer, $<i>1); }
    | Boolean
            { $$ = buildIntTree(Boolean, $<i>1); }
    ;

idlist
    : Ident
            { $$ = buildIntTree(Ident, $1); }
    | Ident Comma idlist
            { $$ = buildTree(Comma, buildIntTree(Ident, $1), $3, NULL); }   
    ;

arraydecl
    : Array arraylist
            { $$ = buildTree(Array, $2, NULL, NULL); }
    | type Array arraylist
            { $$ = buildTree(Array, $1, $3, NULL); }
    ;

arraylist
    : arrayseg
            { $$ = $1; }
    | arrayseg Comma arraylist
            { $$ = buildTree(Comma, $1, NULL, NULL);$$->next=$3 ; }
    ;

arrayseg
    : Ident LBrak a_expr Colon a_expr RBrak
            { $$ = buildTree(LBrak, buildIntTree(Ident, $1), $3, $5); }
    ;

stmts
    : stmt
            { $$ = $1; }
    | stmt Semi stmts
            { $$ = buildTree(Semi, $1, NULL, NULL);$$->next=$3 ; }
    ;

stmt
    : u_stmt
    | if_stmt
    | for_stmt
    ;

u_stmt
    : assign
    | dummy
    | block
    ;

assign
    : var Assign expr
            { $$ = buildTree(Assign, $1, $3, NULL); }
    | var Assign assign
            { $$ = buildTree(Assign, $1, NULL, NULL);$$->next=$3; }
    ;

dummy
    : /* empty */
            { $$ = NULL; }
    ;

for_stmt
    : For var Assign a_expr Step a_expr Until a_expr Do stmt
            { $$ = buildTree(For, $2, $4, buildTree(Step, $6, $8, $10)); }
    ;

if_stmt
    : If expr Then u_stmt
            { $$ = buildTree(If, $2, $4, NULL); }
    | If expr Then u_stmt Else stmt
            { $$ = buildTree(If, $2, $4, $6); }
    | If expr Then for_stmt
            { $$ = buildTree(If, $2, $4, NULL); }
    ;

var
    : Ident
            { $$ = buildIntTree(Ident, $1); }
    | Ident LBrak a_expr RBrak
            { $$ = buildTree(LBrak, buildIntTree(Ident, $1), $3, NULL); }
    ;

factor
    : IntConst
            { $$ = buildIntTree(IntConst, $1); }
    | RealConst
            { $$ = buildFloatTree(RealConst, $1); }
    | var
            { $$ = $1; }
    | LParan expr RParan
            /* {$$ = buildTree(LParen, $2, NULL, NULL);} */
            { $$ = $2; }
    ;

term
    : factor
            { $$ =$1; }
    | term Mult factor
            { $$ = buildTree(Mult, $1, $3, NULL); }
    | term Divide factor
            { $$ = buildTree(Divide, $1, $3, NULL); }
    | term Div factor
            { $$ = buildTree(Div, $1, $3, NULL); }
    ;

sum
    : term
            { $$ = $1; }
    | Plus term
            { $$ = buildTree(Plus, $2, NULL, NULL); }
    | Minus term
            { $$ = buildTree(Minus, $2, NULL, NULL); }
    | sum Plus term
            { $$ = buildTree(Plus, $1, $3, NULL); }
    | sum Minus term
            { $$ = buildTree(Minus, $1, $3, NULL); }
    ;

brel
    : sum
            { $$ = $1; }
    | True
            { $$ = buildTree(True, NULL, NULL, NULL); }
    | False
            { $$ = buildTree(False, NULL, NULL, NULL); }
    | sum relation sum
            { $$ = buildTree($1, $2, $3, NULL); }
    ;

relation
    : Less
            { $$ = buildTree(Less, NULL, NULL, NULL); }
    | LessEq
            { $$ = buildTree(LessEq, NULL, NULL, NULL); }
    | Great
            { $$ = buildTree(Great, NULL, NULL, NULL); }
    | GreatEq
            { $$ = buildTree(GreatEq, NULL, NULL, NULL); }
    | Eq
            { $$ = buildTree(Eq, NULL, NULL, NULL); }
    | NotEq
            { $$ = buildTree(NotEq, NULL, NULL, NULL); }
    ;

bsecond
    : brel
            { $$ = $1; }
    | Not brel
            { $$ = buildTree(Not, $2, NULL, NULL); }
    ;

bfactor
    : bsecond
            { $$ = $1; }
    | bfactor And bsecond
            { $$ = buildTree(And, $1, NULL, NULL); $$->next = $3; }
    ;

bterm
    : bfactor
            { $$ = $1; }
    | bterm Or bfactor
            { $$ = buildTree(Or, $1, NULL, NULL); $$->next = $3; }
    ;

expr    
    : bterm
            { $$ = $1; }
    | If expr Then bterm Else expr
            { $$ = buildTree(If, $2, $4, $6); }
    ;

a_expr
    : sum
            { $$ = $1; }
    | If expr Then sum Else a_expr
            { $$ = buildTree(If, $2, $4, $6); }
    ; 

%%

lex 文件:

%{

#include <stdlib.h>
#include <stdio.h>
#include "y.tab.h"
#include "tree.h"

int line_num = 1, position = 1;;

%}

L       [A-Za-z]
I       [0-9]
R       [0-9][0-9]*\.[0-9][0-9] 

%%

^".C".*         /* comment */;
[ \t]+            position += yyleng;
"and"           { position += 3; return And; }
"array"         { position += 5; return Array; }
"begin"         { position += 5; return Begin; }
"boolean"       { position += 7; return Boolean; }
"div"           { position += 3; return Div; }
"do"            { position += 2; return Do; }
"else"          { position += 4; return Else; }
"end"           { position += 3; return End; }
"false"         { position += 5; return False; }
"for"           { position += 3; return For; }
"goto"          { position += 4; return Goto; }
"if"            { position += 2; return If; }
"imply"         { position += 5; return Imply; }
"integer"       { position += 7; return Integer; }
"label"         { position += 5; return Label; }
"not"           { position += 3; return Not; }
"or"            { position += 2; return Or; }
"own"           { position += 3; return Own; }
"procedure"     { position += 9; return Procedure; }
"real"          { position += 4; return Real; }
"step"          { position += 4; return Step; }
"string"        { position += 6; return String; }
"then"          { position += 4; return Then; }
"true"          { position += 4; return True; }
"until"         { position += 5; return Until; }
"value"         { position += 5; return Value; }
"while"         { position += 5; return While; }

{L}({L}|{I})*   { position += yyleng; yylval.i = lookup (yytext); return Ident; }        
{I}+            { position += yyleng; yylval.i = atoi (yytext); return IntConst; }
{R}*            { position += yyleng; yylval.f = atof (yytext); return RealConst; }

"+"             { position += 1; return Plus; }
"-"             { position += 1; return Minus; }
"*"             { position += 1; return Mult; }
"/"             { position += 1; return Div; }
"<"             { position += 1; return Less; }
"<="            { position += 2; return LessEq; }
">"             { position += 1; return Great; }
">="            { position += 2; return GreatEq; }
"="             { position += 1; return Eq; }
"!="            { position += 2; return NotEq; }
","             { position += 1; return Comma; }
":"             { position += 1; return Colon; }
";"             { position += 1; return Semi; }
"("             { position += 1; return LParan; }
")"             { position += 1; return RParan; }
"["             { position += 1; return LBrak; }
"]"             { position += 1; return RBrak; }
":="            { position += 2; return Assign; }
"\n"            { line_num++; position = 1; newline(); }
.               { position += 1; yyerror ("Bad Character"); } 

%%

int yyerror (char strg[]) {
    printf("Error: %s at line %d, position %d, token %s\n", strg, line_num, position, yytext);
}

typedef char name[20];
    static char Names[200][20] = { "<no name>" };
    int top = 0;

int lookup (char strg[]) {
    int i;
    for (i = 0; i <= top; i++)
        if (strcmp (strg, Names[i]) == 0) return i;
    strcpy (Names[++top], strg);
    return top;
}

void printNames (void) {
    int i = 0;
    for (; i <= top; i++)
        printf("%d\t%strg\n", i, Names[i]);
}

char *id_name (int i) {
    return Names[i];
}

树.c:

#include <stdio.h>
#include "tree.h"
#include "y.tab.h"

tree buildTree (int kind, tree one, tree two, tree three)
{
    tree t = (tree)malloc(sizeof (node));
    t->kind = kind;
    t->first = one;
    t->second = two;
    t->third = three;
    t->next = NULL;
    return t;
}

tree buildIntTree (int kind, int val)
{
    tree t = (tree)malloc(sizeof (node));
    t->kind = kind;
    t->value = val;
    t->first = t->second = t->third = NULL;
    t->next = NULL;
    return t;
}

tree buildFloatTree (int kind, float f_val)
{
    tree t;
    t->kind = kind;
    t->value = f_val;
    t->first = t->second = t->third = NULL;
    t->next = NULL;
    return t; 
}

char TokName[][12] = 
    {"<eof>", 
    "Ident", "IntConst", "", "", "", "", "", "", "", "",
    "IF", "THEN", "END", "WHILE", "DO", "ELSE", "", "", "", "",
    "=", "(", ")", "+", "-", "*", "/", ".EQ.", ".NE.", ".LT.",
    ".LE.", ".GT.", ".GE.", "<eoln>", "+", "-", "", "", "", "",
    "<NoType>", "<IntType>", "<BoolType>", "<Prog>", "<Comma>"};
static int indent = 0;
void printTree (tree t)
{
    if (t == NULL) return;
    for (; t != NULL; t = t->next) {
            printf ("%*s%s", indent, "", TokName[t->kind]);
            switch (t->kind) {
                    case Ident: 
                            printf ("  %s (%d)\n", id_name (t->value), t->value);
                            break;
                    case IntConst:
                            printf ("  %d\n", t->value);
                            break;
                    default:
                            printf ("\n");
                            indent += 2;
                            printTree (t->first);
                            printTree (t->second);
                            printTree (t->third);
                            indent -= 2;
                    }
            }
}

树.h:

ypedef struct Node {
    int kind, value;
    float f_val;
    struct Node *first, *second, *third, *next;
} node;
typedef node *tree;

extern char TokName[][12];

tree buildTree (int kind, tree first, tree second, tree third);
tree buildIntTree (int kind, int val);
tree buildFloatTree (int kind, float f_val);
void printTree (tree);

最后是 main.c:

#include <stdio.h>
#include "tree.h"

extern FILE *yyin;
extern int yydebug;
tree root;

FILE    *outfile;

main (int argc, char **argv)
{
    if (argc != 2) { 
            fprintf (stderr, "%s: Insufficient Arguments\n", argv[0]); 
            exit(1);
            }
//      if ((yyin = freopen (argv[1], "r", yyin)) == 0L) {
    if ((yyin = fopen (argv[1], "r")) == 0L) {
            fprintf (stderr, "%s: Can't open Input File %s\n", argv[0], argv[1]); 
            exit(1);
            }

    yyparse();
    printTree (root);
    close (yyin);
}

最佳答案

您的扫描程序(lex 文件)需要有#include "tree.h" 之前 #include "y.tab.h" > -- 交换这两行,它应该可以编译。

关于c - lex/yacc 项目编译时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24854054/

相关文章:

c - 如何解决这个语义错误?

java - 在 Java 中类型转换或解码 C 对象

C - 更改矩阵的最后一个元素

c++ - 如何获取 headers 作为 flex 和 bison 的输出?

qt - 使用 qt : How To Build a Gui OnTop Of a Console Application?

c - 从 main.c 调用 yyin 和 yyparse 时出错

c - 用于调用函数的 x86 汇编宏(带参数)

macos - 为什么我的 Mac (OS X 10.7.3) 有一个旧版本 (2.3) 的 Gnu Bison?

C with Bison+Flex 检查规则文件

emacs - lex/flex/yacc/bison文件是否有良好的Emacs模式或方法?