calc.yy (3268B)
- /* Ãæ´ÖµË¡ÅÅÂî -- calc */
- %{
- typedef double NumType;
- #define YYSTYPE double
- #define YYERROR_VERBOSE
- #include <cmath>
- #include <cctype>
- #include <cstring>
- #include <vector>
- #include <sstream>
- #include <string.h>
- #include "calc.h"
- #include "formula.h"
- #include "formula-variables.h"
- extern void yyerror(const char* s);
- extern int yylex();
- const char* yyinStr;
- typedef Formula<NumType> CalcFormula;
- typedef Number<NumType> CalcNumber;
- typedef Random<NumType> CalcRandom;
- typedef Rank<NumType> CalcRank;
- typedef Param<NumType> CalcParam;
- typedef Operator CalcOperator;
- namespace {
- CalcFormula* formula;
- std::vector<CalcFormula*> formulas;
- CalcFormula* f(double d) { return formulas[(int)d]; }
- int paramId;
- }
- %}
- /* BISONÀë¸À */
- %token NUM RAND RANK PARAM
- %left '-' '+'
- %left '*' '/'
- %left NEG /* negation--ñ¹à¥Þ¥¤¥Ê¥¹ */
- %right '^' /* ¤Ù¤¾è´Ø¿ô */
- /* ʸˡµ¬Â§¤¬Â³¤¯ */
- %%
- input: /* ¶õʸ»úÎó */
- | input line
- ;
- line: '\n'
- | exp '\n' { formula = f($1); return 0; }
- ;
- exp: NUM {
- $$ = formulas.size();
- formulas.push_back(new CalcFormula(new CalcNumber($1)));
- }
- | RAND {
- $$ = formulas.size();
- formulas.push_back(new CalcFormula(new CalcRandom()));
- }
- | RANK {
- $$ = formulas.size();
- formulas.push_back(new CalcFormula(new CalcRank()));
- }
- | PARAM {
- $$ = formulas.size();
- formulas.push_back(new CalcFormula(new CalcParam(paramId)));
- }
- | exp '+' exp {
- $$ = formulas.size();
- formulas.push_back(new CalcFormula(f($1), op_add, f($3)));
- }
- | exp '-' exp {
- $$ = formulas.size();
- formulas.push_back(new CalcFormula(f($1), op_sub, f($3)));
- }
- | exp '*' exp {
- $$ = formulas.size();
- formulas.push_back(new CalcFormula(f($1), op_mul, f($3)));
- }
- | exp '/' exp {
- $$ = formulas.size();
- formulas.push_back(new CalcFormula(f($1), op_div, f($3)));
- }
- | '-' exp %prec NEG {
- $$ = $2;
- f($2)->setHeadSub();
- }
- | '(' exp ')' {
- $$ = $2;
- }
- ;
- %%
- /**
- * »ú¶ç²òÀÏ´ï¤Ï¡¢¿ôÃͤòÆɤá¤Ð¡¢double·¿¤ÎÃͤò¥¹¥¿¥Ã¥¯¤ËÀѤó¤Ç
- * ¥È¡¼¥¯¥ó¡ÖNUM¡×¤òÊÖ¤·¡¢¿ôÃͰʳ°¤òÆɤá¤Ð¡¢¤½¤Îʸ»ú¤Î¥¢¥¹¥¡¼Éä¹æ¤òÊÖ¤¹¡£
- * ¶õÇò¤È¥¿¥Ö¤ÏÆɤßÈô¤Ð¤µ¤ì¤ë¡£¥Õ¥¡¥¤¥ë¤¬½ª¤ï¤ë¤È0¤òÊÖ¤¹¡£
- */
- #include <ctype.h>
- #include <stdio.h>
- int yylex ()
- {
- int c;
- /* ¶õÇòÎà¤òÆɤßÈô¤Ð¤¹ */
- while ((c = *(yyinStr++)) == ' ' || c == '\t')
- ;
- /* ¿ôÃͤò½èÍý¤¹¤ë */
- if (c == '.' || isdigit (c))
- {
- yyinStr--;
- sscanf (yyinStr, "%lf", &yylval);
- while ((c = *(++yyinStr)) == '.' || isdigit(c)) {}
- return NUM;
- }
- // ÊÑ¿ô¤ò½èÍý¤¹¤ë */
- if (c == '$') {
- if (strncmp(yyinStr, "rand", 4) == 0) {
- yyinStr += 4;
- return RAND;
- }
- else if (strncmp(yyinStr, "rank", 4) == 0) {
- yyinStr += 4;
- return RANK;
- }
- else {
- std::istringstream iss(std::string(yyinStr).substr(0, 1));
- iss >> paramId;
- yyinStr++;
- return PARAM;
- }
- }
- /* ¥Õ¥¡¥¤¥ë¤Î½ª¤ï¤ê¤ò½èÍý¤¹¤ë */
- if (c == '\0')
- return 0;
- /* 1ʸ»ú¤òÊÖ¤¹ */
- return c;
- }
- void yyerror(const char* s) {
- printf("yyerror: %s\n", s);
- }
- std::auto_ptr<CalcFormula> calc(const std::string& str) {
- std::string fml = str + '\n';
- yyinStr = fml.c_str();
- yyparse();
- return std::auto_ptr<CalcFormula>(formula);
- }