Previous: Mfcalc Rules, Up: Multi-function Calc   [Contents][Index]


2.4.3 mfcalc¤Îµ­¹æÉ½

ÊÑ¿ô¤È´Ø¿ô¤Î̾Á°¤È°ÕÌ£¤òÊÝ»ý¤¹¤ë¤¿¤á¤Ë¡¢ ¿µ¡Ç½ÅÅÂî¤Ïµ­¹æÉ½¤òɬÍפȤ·¤Þ¤¹¡£ ¤³¤ì¤Ï¡¢¥¢¥¯¥·¥ç¥ó¤ò½ü¤¯Ê¸Ë¡µ¬Â§¤ÈBisonÀë¸À¤Ë¤Ï±Æ¶Á¤·¤Þ¤»¤ó¤¬¡¢ ÄɲäÎC¤Î´Ø¿ô¤¬¤¤¤¯¤Ä¤«É¬ÍפǤ¹¡£

µ­¹æÉ½¤Ï¡¢¥ì¥³¡¼¥É¤Î¥ê¥ó¥¯¥ê¥¹¥È¤«¤é¤Ê¤ê¤Þ¤¹¡£ ¤½¤ÎÄêµÁ¤Ï¡¢¸å½Ò¤Î¡¢¥Ø¥Ã¥À¥Õ¥¡¥¤¥ëcalc.h¤Ë¤¢¤ê¤Þ¤¹¡£ ´Ø¿ô¤ÈÊÑ¿ô¤ÎξÊý¤òɽ¤ËÃÖ¤¯¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

/* µ­¹æÉ½¤Î¥ê¥ó¥¯¤òɽ¤¹¥Ç¡¼¥¿·¿                 */
struct symrec
{
  char *name;  /* µ­¹æ¤Î̾Á°                    */
  int type;    /* µ­¹æ¤Î¼ïÎà¡§VAR¤Þ¤¿¤ÏFNCT     */
  union {
    double var;           /* VAR¤ÎÃÍ            */
    double (*fnctptr)();  /* FNCT¤ÎÃÍ           */
  } value;
  struct symrec *next;    /* ¼¡¤Î¹àÌܤؤΥê¥ó¥¯ */
};
typedef struct symrec symrec;

/* `struct symrec'¤Î¥ê¥ó¥¯¤Ç¤¢¤ëµ­¹æÉ½          */
extern symrec *sym_table;

symrec *putsym ();
symrec *getsym ();

¿·¤·¤¤main´Ø¿ô¤Ï¡¢µ­¹æÉ½¤ò½é´ü²½¤¹¤ë´Ø¿ô¤Ç¤¢¤ë init_table¤ò¸Æ¤Ó¤Þ¤¹¡£ main¤Èinit_table¤ò°Ê²¼¤Ë¼¨¤·¤Þ¤¹¡£

#include <stdio.h>

main ()
{
  init_table ();
  yyparse ();
}
yyerror (s)  /* ¥¨¥é¡¼¤¬¤¢¤ë¤Èyyparse¤«¤é¸Æ¤Ó½Ð¤µ¤ì¤ë */
     char *s;
{
  printf ("%s\n", s);
}

struct init
{
  char *fname;
  double (*fnct)();
};
struct init arith_fncts[]
  = {
      "sin", sin,
      "cos", cos,
      "atan", atan,
      "ln", log,
      "exp", exp,
      "sqrt", sqrt,
      0, 0
    };

/* µ­¹æÉ½¡§`struct symrec'¤Î¥ê¥¹¥È       */
symrec *sym_table = (symrec *)0;
init_table ()  /* ¿ô³Ø´Ø¿ô¤òɽ¤ËÅÐÏ¿¤¹¤ë */
{
  int i;
  symrec *ptr;
  for (i = 0; arith_fncts[i].fname != 0; i++)
    {
      ptr = putsym (arith_fncts[i].fname, FNCT);
      ptr->value.fnctptr = arith_fncts[i].fnct;
    }
}

ñ½ã¤Ë½é´ü²½¥ê¥¹¥È¤òÊÔ½¸¤·¤Æ¡¢É¬Íפʥ¤¥ó¥¯¥ë¡¼¥É¥Õ¥¡¥¤¥ë¤òÄɲ乤ë¤À¤±¤Ç¡¢ ÅÅÂî¤Ë´Ø¿ô¤òÄɲäǤ­¤Þ¤¹¡£

µ­¹æÉ½¤Ëµ­¹æ¤òÅÐÏ¿¤·¤Æ¸¡º÷¤¹¤ë¤¿¤á¤Ë¡¢2¸Ä¤Î½ÅÍפʴؿô¤¬¤¢¤ê¤Þ¤¹¡£ ´Ø¿ôputsym¤Ï¡¢ÅÐÏ¿¤¹¤Ù¤­¥ª¥Ö¥¸¥§¥¯¥È¤Î ̾Á°¤È·¿¡ÊVAR¤äFNCT¡Ë¤òÅϤµ¤ì¤Þ¤¹¡£ ¥ª¥Ö¥¸¥§¥¯¥È¤Ï¥ê¥¹¥È¤ÎÀèÆ¬¤Ë¥ê¥ó¥¯¤µ¤ì¡¢ ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£ ´Ø¿ôgetsym¤Ï¡¢¸¡º÷¤¹¤Ù¤­µ­¹æ¤Î̾Á°¤òÅϤµ¤ì¤Þ¤¹¡£ ¤â¤·¸«¤Ä¤«¤ì¤Ðµ­¹æ¤Ø¤Î¥Ý¥¤¥ó¥¿¤¬ÊÖ¤µ¤ì¡¢ ¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð0¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£

symrec *
putsym (sym_name,sym_type)
     char *sym_name;
     int sym_type;
{
  symrec *ptr;
  ptr = (symrec *) malloc (sizeof (symrec));
  ptr->name = (char *) malloc (strlen (sym_name) + 1);
  strcpy (ptr->name,sym_name);
  ptr->type = sym_type;
  ptr->value.var = 0; /* ´Ø¿ô¤Î¾ì¹ç¤Ë¤âÃͤò0¤Ë¤¹¤ë */
  ptr->next = (struct symrec *)sym_table;
  sym_table = ptr;
  return ptr;
}

symrec *
getsym (sym_name)
     char *sym_name;
{
  symrec *ptr;
  for (ptr = sym_table; ptr != (symrec *) 0;
       ptr = (symrec *)ptr->next)
    if (strcmp (ptr->name,sym_name) == 0)
      return ptr;
  return 0;
}

º£Å٤δؿôyylex¤Ï¡¢ÊÑ¿ô¡¢¿ôÃÍ¡¢1ʸ»ú¤Î»»½Ñ±é»»»Ò¤ò ǧ¼±¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ ±Ñ»ú¤Ç»Ï¤Þ¤ê±Ñ¿ô»ú¤«¤é¤Ê¤ëʸ»úÎó¤Ï¡¢µ­¹æÉ½¤Ë¤É¤¦½ñ¤«¤ì¤Æ¤¤¤ë¤«¤Ë±þ¤¸¤Æ¡¢ ÊÑ¿ô¤È´Ø¿ô¤Î¤É¤Á¤é¤È¤âǧ¼±¤µ¤ì¤Þ¤¹¡£

ʸ»úÎó¤Ï¡¢µ­¹æÉ½¤ò¸¡º÷¤¹¤ë¤¿¤á¤Ëgetsym¤ËÅϤµ¤ì¤Þ¤¹¡£ ¤â¤·Ì¾Á°¤¬É½¤Ë¤¢¤ì¤Ð¡¢¤½¤Î¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤È ̾Á°¤Î·¿¡ÊVAR¤Þ¤¿¤ÏFNCT¡Ë¤¬¡¢ yyparse¤ËÊÖ¤µ¤ì¤Þ¤¹¡£ ̾Á°¤¬¤Þ¤Àɽ¤Ë¤Ê¤±¤ì¤Ð¡¢putsym¤ò»È¤Ã¤Æ¡¢ VAR¤È¤·¤ÆÅÐÏ¿¤µ¤ì¤Þ¤¹¡£ ¤½¤·¤Æ¡¢¥Ý¥¤¥ó¥¿¤È·¿¡Ê¤³¤Î¾ì¹ç¤Ë¤Ïɬ¤ºVAR¡Ë¤¬ yyparse¤ËÊÖ¤µ¤ì¤Þ¤¹¡£

yylex¤ÎÃæ¤Ç¡¢¿ôÃͤȻ»½Ñ±é»»»Ò¤Î°·¤¤¤Ë´Ø¤¹¤ëÉôʬ¤Ï¡¢ Êѹ¹¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤»¤ó¡£

#include <ctype.h>
yylex ()
{
  int c;

  /* ¶õÇò¤òÆÉ¤ßÈô¤Ð¤·¡¢¶õÇò°Ê³°¤òÆÀ¤ë         */
  while ((c = getchar ()) == ' ' || c == '\t');

  if (c == EOF)
    return 0;
  /* ¿ôÃͤòÆÉ¤à   */
  if (c == '.' || isdigit (c))
    {
      ungetc (c, stdin);
      scanf ("%lf", &yylval.val);
      return NUM;
    }
  /* ¼±Ê̻ҤòÆÉ¤à */
  if (isalpha (c))
    {
      symrec *s;
      static char *symbuf = 0;
      static int length = 0;
      int i;
      /* ¥Ð¥Ã¥Õ¥¡¤ÎŤµ¤Î½é´üÃͤÏ40ʸ»ú       */
      if (length == 0)
        length = 40, symbuf = (char *)malloc (length + 1);

      i = 0;
      do
        {
          /* ¤¢¤Õ¤ì¤¿¤Î¤Ç¥Ð¥Ã¥Õ¥¡¤òÂ礭¤¯¤¹¤ë */
          if (i == length)
            {
              length *= 2;
              symbuf = (char *)realloc (symbuf, length + 1);
            }
          /* ʸ»ú¤ò¥Ð¥Ã¥Õ¥¡¤ËÊѤ¨¤ë           */
          symbuf[i++] = c;
          /* ¼¡¤Îʸ»ú¤òÆÉ¤à                   */
          c = getchar ();
        }
      while (c != EOF && isalnum (c));

      ungetc (c, stdin);
      symbuf[i] = '\0';
      s = getsym (symbuf);
      if (s == 0)
        s = putsym (symbuf, VAR);
      yylval.tptr = s;
      return s->type;
    }

  /* ¤½¤Î¾¤Îʸ»ú¤Ïʸ»ú¥ê¥Æ¥é¥ë¥È¡¼¥¯¥ó       */
  return c;
}

¤³¤Î¥×¥í¥°¥é¥à¤Ï¡¢¶¯ÎϤ«¤Ä½ÀÆð¤Ç¤¹¡£ ¿·¤·¤¤´Ø¿ô¤ÎÄɲäϴÊñ¤Ç¤¹¡£ pi¤äe¤Î¤è¤¦¤Ë¤¢¤é¤«¤¸¤áÄêµÁ¤µ¤ì¤¿ÊÑ¿ô¤òÄɲ乤뤿¤á¤Ë ¥×¥í¥°¥é¥à¤òÊѹ¹¤¹¤ë¤³¤È¤Ï¡¢´Êñ¤Ê»Å»ö¤Ç¤·¤ç¤¦¡£


Previous: Mfcalc Rules, Up: Multi-function Calc   [Contents][Index]