gperf的学习笔记(一)

本文介绍了一个用于解析特定格式输入文件的C++类Input,该类能够处理声明、关键字定义及函数等内容,并将其划分为声明、关键字和函数三个部分。文章详细展示了如何通过逐行检查来确定每一行是否包含声明,并提供了读取声明参数值的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

输入部分,用类Input

class Input
{
public:
                        Input (FILE *stream, Keyword_Factory *keyword_factory);
                        ~Input ();
  void                  read_input ();
private:
  /* Input stream.  */
  FILE *                _stream;
  /* Creates the keywords.  */
  Keyword_Factory * const _factory;
public:
  /* Memory block containing the entire input.  */
  char *                _input;
  char *                _input_end;
  /* The C code from the declarations section.  */
  const char *          _verbatim_declarations;
  const char *          _verbatim_declarations_end;
  unsigned int          _verbatim_declarations_lineno;
  /* The C code from the end of the file.  */
  const char *          _verbatim_code;
  const char *          _verbatim_code_end;
  unsigned int          _verbatim_code_lineno;
  /* Declaration of struct type for a keyword and its attributes.  */
  const char *          _struct_decl;
  unsigned int          _struct_decl_lineno;
  /* Return type of the lookup function.  */
  const char *          _return_type;
  /* Shorthand for user-defined struct tag type.  */
  const char *          _struct_tag;
  /* List of all keywords.  */
  Keyword_List *        _head;
  /* Whether the keyword chars would have different values in a different
     character set.  */
  bool                  _charset_dependent;
};

判断声明:

static bool
is_declaration (const char *line, const char *line_end, unsigned int lineno,
                const char *decl)
{
  /* Skip '%'.  */
  line++;

  /* Skip DECL.  */
  for (const char *d = decl; *d; d++)
    {
      if (!(line < line_end))
        return false;
      if (!(*line == *d || (*d == '-' && *line == '_')))
        return false;
      line++;
    }
  if (line < line_end
      && ((*line >= 'A' && *line <= 'Z')
          || (*line >= 'a' && *line <= 'z')
          || *line == '-' || *line == '_'))
    return false;

  /* OK, found DECL.  */

  /* Skip whitespace.  */
  while (line < line_end && (*line == ' ' || *line == '\t'))
    line++;

  /* Expect end of line.  */
  if (line < line_end && *line != '\n')
    {
      fprintf (stderr, "%s:%u: junk after declaration\n",
               pretty_input_file_name (), lineno);
      exit (1);
    }

  return true;
}

读取声明的参数值 :
/* Tests if the given line contains a "%DECL=ARG" declaration.
   If yes, it sets *ARGP to the argument, and returns true.
   Otherwise, it returns false.  */
static bool
is_declaration_with_arg (const char *line, const char *line_end,
                         unsigned int lineno,
                         const char *decl, char **argp)
{
  /* Skip '%'.  */
  line++;

  /* Skip DECL.  */
  for (const char *d = decl; *d; d++)
    {
      if (!(line < line_end))
        return false;
      if (!(*line == *d || (*d == '-' && *line == '_')))
        return false;
      line++;
    }
  if (line < line_end
      && ((*line >= 'A' && *line <= 'Z')
          || (*line >= 'a' && *line <= 'z')
          || *line == '-' || *line == '_'))
    return false;

  /* OK, found DECL.  */

  /* Skip '='.  */
  if (!(line < line_end && *line == '='))
    {
      fprintf (stderr, "%s:%u: missing argument in %%%s=ARG declaration.\n",
               pretty_input_file_name (), lineno, decl);
      exit (1);
    }
  line++;

  /* The next word is the argument.  */
  char *arg = new char[line_end - line + 1];
  char *p = arg;
  while (line < line_end && !(*line == ' ' || *line == '\t' || *line == '\n'))
    *p++ = *line++;
  *p = '\0';

  /* Skip whitespace.  */
  while (line < line_end && (*line == ' ' || *line == '\t'))
    line++;

  /* Expect end of line.  */
  if (line < line_end && *line != '\n')
    {
      fprintf (stderr, "%s:%u: junk after declaration\n",
               pretty_input_file_name (), lineno);
      exit (1);
    }

  *argp = arg;
  return true;
}

声明为%define decl arg类型:

static bool
is_define_declaration (const char *line, const char *line_end,
                       unsigned int lineno,
                       const char *decl, char **argp)
{
  /* Skip '%'.  */
  line++;

  /* Skip "define".  */
  {
    for (const char *d = "define"; *d; d++)
      {
        if (!(line < line_end))
          return false;
        if (!(*line == *d))
          return false;
        line++;
      }
    if (!(line < line_end && (*line == ' ' || *line == '\t')))
      return false;
  }

  /* Skip whitespace.  */
  while (line < line_end && (*line == ' ' || *line == '\t'))
    line++;

  /* Skip DECL.  */
  for (const char *d = decl; *d; d++)
    {
      if (!(line < line_end))
        return false;
      if (!(*line == *d || (*d == '-' && *line == '_')))
        return false;
      line++;
    }
  if (line < line_end
      && ((*line >= 'A' && *line <= 'Z')
          || (*line >= 'a' && *line <= 'z')
          || *line == '-' || *line == '_'))
    return false;

  /* OK, found DECL.  */

  /* Skip whitespace.  */
  if (!(line < line_end && (*line == ' ' || *line == '\t')))
    {
      fprintf (stderr, "%s:%u:"
               " missing argument in %%define %s ARG declaration.\n",
               pretty_input_file_name (), lineno, decl);
      exit (1);
    }
  do
    line++;
  while (line < line_end && (*line == ' ' || *line == '\t'));

  /* The next word is the argument.  */
  char *arg = new char[line_end - line + 1];
  char *p = arg;
  while (line < line_end && !(*line == ' ' || *line == '\t' || *line == '\n'))
    *p++ = *line++;
  *p = '\0';

  /* Skip whitespace.  */
  while (line < line_end && (*line == ' ' || *line == '\t'))
    line++;

  /* Expect end of line.  */
  if (line < line_end && *line != '\n')
    {
      fprintf (stderr, "%s:%u: junk after declaration\n",
               pretty_input_file_name (), lineno);
      exit (1);
    }

  *argp = arg;
  return true;
}


Input::read_input中的将输入分为三部分的代码:声明,关键字,函数

/* Break up the input into the three sections.  */
  {
    const char *separator[2] = { NULL, NULL };
    unsigned int separator_lineno[2] = { 0, 0 };
    int separators = 0;
    {
      unsigned int lineno = 1;
      for (const char *p = input; p < input_end; )
        {
          if (p[0] == '%' && p[1] == '%')
            {
              separator[separators] = p;
              separator_lineno[separators] = lineno;
              if (++separators == 2)
                break;
            }
          lineno++;
          p = (const char *) memchr (p, '\n', input_end - p);
          if (p != NULL)
            p++;
          else
            p = input_end;
        }
    }

判断有无声明:

bool has_declarations;
    if (separators == 1)
      {
        if (option[TYPE])
          has_declarations = true;
        else
          {
            has_declarations = false;
            for (const char *p = input; p < separator[0]; )
              {
                if (p[0] == '%')
                  {
                    has_declarations = true;
                    break;
                  }
                p = (const char *) memchr (p, '\n', separator[0] - p);
                if (p != NULL)
                  p++;
                else
                  p = separator[0];
              }
          }
      }
    else
      has_declarations = (separators > 0);



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值