宿題として、+操作しかできない基本的な計算機があり、より多くの関数を実装する必要があります。角かっこ演算子、符号演算子、および最小最大関数を実装する必要がありました。最後のタスクの1つは、min / max関数を拡張して、3つ以上のパラメーターを使用してmin / maxを計算することです。これが、現在行き詰まっているタスクです。
私の現在のcalc.llexファイル:
%{
extern int yylval;
extern int sym[];
extern int yyerror(char *s);
#include "y.tab.h"
%}
%%
[a-z] {
yylval = *yytext - 'a';
return VARIABLE;
}
[0-9]+ {
yylval = atoi(yytext);
return INTEGER;
}
[(),] { return *yytext; }
":=" return ASSIGN;
"+" return PLUS;
"-" return MINUS;
"/" return DIVIDE;
"%" return MODULO;
"*" return TIMES;
"<" return SMAS;
"<=" return SMGAS;
"==" return IS;
"!=" return NOTIS;
">=" return BGGAS;
">" return BGAS;
"min" return MIN;
"max" return MAX;
"\n" return NEWLINE;
[ \t] ;
. yyerror("Invalid character");
%%
int yywrap() {
return 1;
}
私の現在のcalc.yyaccファイル:
%{
#include <stdio.h>
int sym[26];
int yylex();
int yyerror(char *s);
%}
%token VARIABLE ASSIGN INTEGER NEWLINE
%left PLUS
%left TIMES
%left MINUS
%left DIVIDE
%left MODULO
%left UMINUS
%left UPLUS
%left SMAS SMGAS IS NOTIS BGAS BGGAS
%left MIN MAX
%%
program: program statement
|
;
statement: expr NEWLINE
{ printf("%d\n", $1); }
| VARIABLE ASSIGN expr NEWLINE
{ sym[$1] = $3; }
;
expr: INTEGER { $$ = $1; }
| VARIABLE { $$ = sym[$1]; }
| expr PLUS expr { $$ = $1 + $3; }
| expr TIMES expr { $$ = $1 * $3; }
| expr MINUS expr { $$ = $1 - $3; }
| expr DIVIDE expr { $$ = $1 / $3; }
| expr MODULO expr { $$ = $1 % $3; }
| '(' expr ')' { $$ = $2; }
| MINUS expr %prec UMINUS { $$ = -$2; }
| PLUS expr %prec UPLUS { $$ = $2; }
| expr SMAS expr { $$ = $1 < $3; }
| expr SMGAS expr { $$ = $1 <= $3; }
| expr IS expr { $$ = $1 == $3; }
| expr NOTIS expr { $$ = $1 != $3; }
| expr BGGAS expr { $$ = $1 >= $3; }
| expr BGAS expr { $$ = $1 > $3; }
| MIN '(' expr ',' expr ')' { if ($3 < $5){ $$ = $3; } else if ($3 > $5){ $$ = $5; }; }
| MAX '(' expr ',' expr ')' { if ($3 > $5){ $$ = $3; } else if ($3 < $5){ $$ = $5; }; }
;
%%
int yyerror(char *s) {
fprintf(stderr, "%s\n", s);
return 0;
}
int main() {
yyparse();
return 0;
}
解決策の1つは、min / max関数で各値を、で区切り、計算してからmin / max関数に返すことだと思いますが、実装方法がわかりません。私が考えることができる唯一の解決策はかなり複雑です。プロジェクトはそれほど複雑であってはならないので、私はそれを行う簡単な方法が欠けていると思います。
min(5、6)は必要に応じて5を返し、期待される動作方法は(min 6、7、3)で3を返し、無限の数のパラメーターに使用できます。
アイデアはありますか?
ありがとう!
あなたが必要max(x,y)
とmax(x,y,z,q..)
。
考えられる解決策の1つは、(... x、z ...)を繰り返すことができるため、そのためのルールはほとんど必要ありません。注var
、これは必要な操作を決定するために使用されます。
expr ',' expr { if(var==1){$$=$1>$3?$1:$3;}else{$$=$1<$3?$1:$3;}; }
'(' expr ')' { $$ = $2;}
MAX expr { $$ = $2;}
MAX expr { $$ = $2;}
あなたの*.l
ファイルには外部変数が必要です(それを呼びましょうvar
)extern int var
。
また、可約式のためのルールを追加max
し、min
1または0に私達の変数を設定するであろう:
min { op =0;}
max { op =1;}
ここで、1はMAX、MINは0です。
操作を行う前.l
にvar
最初に設定したいので、これはファイルで行われます。
.y
ファイルで行うとvar
、操作後に設定されます。
変数*.y
もファイルに追加します(int var =0)
。
で.y
ファイルあなたMAX
とMIN
でなければなりません%tokens
。さらに、1位/ 2位に追加,
し%right
ます(COMMA
代わりに使用できます,
)。そうでなければ、もしあなたが持っている..4,5*5,..
なら、最初に比較し、次にそれを掛けます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加