IF Anweisung in Flex bison realisieren

hallo,
weiß selber net warum ich das gemacht habe, stimmt ja ich gebe ja keine eingabe von label ein brauche ich ja auch nicht, aussschließlich will ich ja, das wenn JMP L1 eingegeben wird, dann ausgegeben wir dass keyword JMP wurde benutzt zum Label L1, aber dann ist es doch in Ordnung wenn ich schreibe

Code:
jmp_stmt: JMP ID
	{$$ = newStmtNode(JmpK);
	/*$$->attr.name = strdup($2);*/
	$$->child[0] = $2;	

	}

also folglich müsste doch L1 im Baumknoten abgespeichert werden und bei der Ausgabe mit

Code:
case JmpK:
          printf("JMP\n","to Label: %s\n",tree->attr.name);
          break;

ausgegeben werden

hallo,
jetzt fällt mir wieder ein warum ich label genutzt hatte, da mein Code ja mit :L1 beginnt, dann muss ich doch eigentlich statt label
den" :" als mein Token bezeichnen und als mein label deklarieren oder.

Gruß
Matrix
 
Hi.
weiß selber net warum ich das gemacht habe, stimmt ja ich gebe ja keine eingabe von label ein brauche ich ja auch nicht, aussschließlich will ich ja, das wenn JMP L1 eingegeben wird, dann ausgegeben wir dass keyword JMP wurde benutzt zum Label L1, aber dann ist es doch in Ordnung wenn ich schreibe

Code:
jmp_stmt: JMP ID
	{$$ = newStmtNode(JmpK);
	/*$$->attr.name = strdup($2);*/
	$$->child[0] = $2;	

	}

also folglich müsste doch L1 im Baumknoten abgespeichert werden und bei der Ausgabe mit

Code:
case JmpK:
          printf("JMP\n","to Label: %s\n",tree->attr.name);
          break;

ausgegeben werden
Wie ist die Eingabe und was wird jetzt ausgegeben?
matrix1 hat gesagt.:
jetzt fällt mir wieder ein warum ich label genutzt hatte, da mein Code ja mit :L1 beginnt, dann muss ich doch eigentlich statt label
den" :" als mein Token bezeichnen und als mein label deklarieren oder.
Im Grunde gibt es 2 Möglichkeiten. Man könnte die Label schon in der lexikalischen Analyse verarbeiten und ein Token LABEL mit dem entsprechenden Bezeichner als Wert zurückgeben:
Code:
:[a-zA-Z][a-zA-Z0-9_]*  { yylval.name = strdup(yytext + 1); return LABEL; }
Oder (wie zuerst vorgeschlagen), man liefert einfach den Doppelpunkt als TOKEN zurück und behandelt ein Label als ein Nichtterminal in der Grammatik als eine Folge von ':' ID.

Gruß
 
hallo,
ok hab die zweite Variante gewählt

lex:
Code:
":" {return yytext[0];}

soll ich dann wenn ich als token deklariere einfach ein : hinschreiben, nimmt er das an
Code:
%token :

Code:
label_stmt: ':' ID

hallo,

die erste Variante würde ja so aussehen:

Code:
:[a-zA-Z][a-zA-Z0-9_]*  { yylval.name = strdup(yytext + 1); return LABEL; }

Code:
%token IF THEN ELSE END REPEAT UNTIL SCAN PRINT ID NUM EQUAL FOR WHILE RETURN JMP LABEL

Code:
%type <tree> read_stmt write_stmt exp simple_exp term factor jmp_stmt label_stmt

Code:
label_stmt: ID LABEL
    { $$ = newStmtNode(LabelK);
      /*$$->child[0] = $2;*/
	$$->attr.name = strdup($2);

    }
 
matrix1 hat gesagt.:
hallo,

die erste Variante würde ja so aussehen:

Code:
label_stmt: ID LABEL
    { $$ = newStmtNode(LabelK);
      /*$$->child[0] = $2;*/
	$$->attr.name = strdup($2);

    }
Nein. Wieso "ID LABEL?
Code:
label_stmt: LABEL 
 { $$ = newStmtNode(LabelK);
   $$.attr.name = $1.name;
  }
Gruß
 
Hallo,
Danke für deine Hilfe.
Nun habe ich mein Label definiert, dann sieht also mein JMP dann so aus:

Code:
label_stmt: ':' ID
    { $$ = newStmtNode(LabelK);
      $$.attr.name = $2.name;
    }

Code:
jmp_stmt: JMP ID
	{$$ = newStmtNode(JmpK);
	/*$$->attr.name = strdup($2);*/
	$$.attr.name = $2.name;	

	}

Gruß
Matrix
 
Du mußt das Ganze doch wirklich nur analog der bereits vorhandenen Regeln machen.
Code:
label_stmt: ':' ID
    { $$ = newStmtNode(LabelK);
      $$.attr.name = $2;
    }

Code:
jmp_stmt: JMP ID
	{$$ = newStmtNode(JmpK);
	$$.attr.name = $2;
	}
Gruß
 
Du mußt das Ganze doch wirklich nur analog der bereits vorhandenen Regeln machen.
Code:
label_stmt: ':' ID
    { $$ = newStmtNode(LabelK);
      $$.attr.name = $2;
    }

Code:
jmp_stmt: JMP ID
	{$$ = newStmtNode(JmpK);
	$$.attr.name = $2;
	}
Gruß

hallo,
Vielen dank nochmal.

aber leider kommen mehrere warnungen:
1 nonterminal useless in grammar: label_stmt
1 rule useless in grammar: label_stmt: ':' ID

was hat das zu bedeuten.danke.

Gruß
Matrix
 
hallo,
Vielen dank nochmal.

aber leider kommen mehrere warnungen:
1 nonterminal useless in grammar: label_stmt
1 rule useless in grammar: label_stmt: ':' ID

was hat das zu bedeuten.danke.
Das heißt nur das eine Regel wie A -> a b eigentlich nutzlos ist, da diese Regel keine Alternativen und keine anderen Nichtterminale enthält. Überall da wo das Nichtterminal (in diesem Fall label_stmt) auftaucht könnte dies auch direkt durch die rechte Seite ersetzen.

Bison entfernt die "nutzlose" Regel um einen kompakteren Parser zu generieren.

Gruß
 
Hallo,

ich habe hier zum Beispiel einen Compiler mit yacc von Albert Gräf
realisiert, hierzu ein kleiner Ausschnitt:

leider in Pascal, aber vielleicht hilft es ja weiter

Gruß
Jens

Code:
${

type
  lbl = record
    else_label: Integer;
    end_label : Integer;
  end;

%}

%type <lbl>

%token TOK_IF TOK_ELSEIF TOK_ELSE



ifExpression
        : expr {
          if fld_counter-2 <= 1 then
          begin
            data_code.Add(#9 + 'fld qword [@null_value]');
            data_code.Add(#9 + 'faddp');
            fld_counter := 0;
          end;

        } ifRelation expr {

          if fld_counter-2 <= 1 then
          begin
            data_code.Add(#9 + 'Fld qword [@null_value]');
            data_code.Add(#9 + 'Faddp');
            fld_counter := 0;
          end;

          handle_expr := true;
          push_values := true;
        }
        ;

ifRelation
        : '='      { if_reltype := 0; }
        | '#'      { if_reltype := 1; }
        | '<'      { if_reltype := 2; }
        | '>'      { if_reltype := 3; }
        | '<' '='  { if_reltype := 4; }
        | '>' '='  { if_reltype := 5; }
        | '<' '>'  { if_reltype := 6; }
        | '=' '<'  { if_reltype := 4; }
        | '=' '>'  { if_reltype := 5; }
        ;

ifStatement
        : TOK_IF {
          push_values := true;
          print_string := true;

          if_counter := if_counter + 1;
        } ifExpression {

          push_values := false;

          $<lbl>$.else_label := new_label+1;
          $<lbl>$.end_label  := new_label;

          if (ist_schon_eval = false) and (in_object_code = false) then
          begin
            data_code.Add(#9 + 'fxch st1');
            data_code.Add(#9 + 'fucompp');
            data_code.Add(#9 + 'fstsw ax');
            data_code.Add(#9 + 'sahf');

            case if_reltype of
              0: begin data_code.Add(#9 + 'jne  near Le' + IntToStr($<lbl>$.else_label)); end;
              1: begin data_code.Add(#9 + 'je   near Le' + IntToStr($<lbl>$.else_label)); end;
              2: begin data_code.Add(#9 + 'jnl  near Le' + IntToStr($<lbl>$.else_label)); end;
              3: begin data_code.Add(#9 + 'jng  near Le' + IntToStr($<lbl>$.else_label)); end;
              4: begin data_code.Add(#9 + 'jnle near Le' + IntToStr($<lbl>$.else_label)); end;
              5: begin data_code.Add(#9 + 'jnge near Le' + IntToStr($<lbl>$.else_label)); end;
              6: begin data_code.Add(#9 + 'je   near Le' + IntToStr($<lbl>$.else_label)); end;
            end;
          end;

          new_label := new_label + 1;
          $<lbl>$.else_label := new_label;

        } StatementSequence {

          //new_label := new_label + 1;
          $<lbl>3.end_label := new_label;

          if (ist_schon_eval = false) and (in_object_code = false) then
          begin
            data_code.Add(#9 + 'jmp near Lj' + IntToStr($<lbl>3.end_label-1));
            data_code.Add('Le'               + IntToStr($<lbl>3.end_label) + ':');
          end else
          if (ist_schon_eval = true) then
          begin
            if if_counter > 1 then
            begin
//              FObjectCode.Add('jmp near Le'+inttostr($<lbl>3.end_label));
//              FObjectCode.Add('::Lj'+inttostr($<lbl>3.end_label+1)+':');
            end;
          end;

          new_label := new_label + 1;
          $<lbl>3.end_label := new_label;

        } elseif_stat TOK_ENDIF {

          if if_counter-1 < 0 then
          raise Exception.Create('ENDIF hier nicht erwartet - IF muss vorrangehen.'+#10+
          inttostr(line_no));

          dec(if_counter);

          if (ist_schon_eval = false) and (in_object_code = false) then
          begin
            data_code.Add(#9   + 'jmp near Lj' + IntToStr($<lbl>4.else_label-1));
            data_code.Add('Lj' +                 IntToStr($<lbl>4.else_label-1) + ':');
          end else
          if ist_schon_eval = true then
          begin
            if (if_counter >= 1) then
            begin
              //showmessage(inttostr(if_counter+$<lbl>4.else_label)+' : '+inttostr($<lbl>4.else_label));
              if ((if_counter+$<lbl>4.else_label) - (($<lbl>4.else_label)-(if_counter+$<lbl>4.else_label))) = 1 then
              FObjectCode.Add(#9 + 'jmp near   Lj' + IntToStr($<lbl>4.else_label)) else
              FObjectCode.Add(#9 + 'jmp near   Lj' + IntToStr($<lbl>4.else_label+4));
            end else
            begin
              FObjectCode.Add(#9   + 'jmp near  Le' + IntToStr($<lbl>4.else_label-1));
              FObjectCode.Add('Lj' +                 IntToStr($<lbl>4.else_label+1) + ':');

              if if_counter < 1 then
              FObjectCode.Add('Le'+IntToStr($<lbl>3.end_label-2) + ':');
            end;
          end;

//          ist_schon_eval := false;
        }
        ;
elseif_stat
        :
        | StatementSequence             {
          $<lbl>$.end_label := new_label;
        }
        | TOK_ELSEIF ifExpression {
          if_counter := if_counter + 1;

          $<lbl>$.else_label := new_label;
          $<lbl>$.end_label  := new_label;

          new_label := new_label + 1;   } StatementSequence {
          new_label := new_label + 1;

          $<lbl>$.end_label := new_label;

          data_code.Add(#9+'jMP near Lj' + IntToStr($<lbl>3.end_label));
          data_code.Add('Le'             + IntToStr($<lbl>3.end_label) + ':');

        } elseif_stat {
          new_label := new_label + 2;
          $<lbl>$.else_label := $<lbl>3.else_label;

          data_code.Add(#9+'jmp near Lj' + IntToStr($<lbl>3.else_label));
          data_code.Add('Lj'             + IntToStr($<lbl>3.else_label) + ':');
        }
        | TOK_ELSE  StatementSequence  { $<lbl>$.end_label := new_label; }
        ;
 
Zurück