2014-07-20 59 views
0

我正在使用lex編譯器& yacc。我有編譯錯誤,我相信如果我可以解決一個項目,其餘部分將落實到位。我編譯項目本身:編譯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。至於版本,我不能告訴你。海灣合作委員會是版本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); } 
    ; 

%% 

萊克斯文件:

%{ 

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

的tree.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; 
        } 
      } 
} 

的tree.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); 
} 
+0

我不能重現錯誤,雖然我沒有足夠的信息來做比模糊的猜測更多的事情。請不要發佈項目的小部分內容,而應發佈顯示錯誤的最小可編譯示例,並指定您正在使用的gcc和yacc的版本。 (我懷疑你正在使用byacc,但它可能是一箇舊版本的野牛。)你是否創建或編輯'y.tab.h'?而且,可選地,爲什麼不讓yacc/bison編號爲令牌而不是強制自己的定義,這很難維護。 – rici

+3

'tree'的定義在解析y.tab.h時需要對編譯器可見。例如。帶有'tree'的.h文件需要包含在scanner.lex中的y.tab.h之前。 –

+0

@rici完整代碼已添加。對不起,我不能「配對」它。 –

回答

1

您的掃描儀的程序(文件法)需要有#include "tree.h"#include "y.tab.h" - 交換這兩行,它應該編譯。