编写tokenizer时遇到问题

时间:2013-10-27 23:11:10

标签: c++ io tokenize

我正在用c ++编写一个tokenizer。它要做的是在文件中搜索用“”括起来的字符串字符,以及符号[和]。它将创建它的标记对象,并将其存储在向量中。它应该通过调用input.get()来跳过它们来忽略所有空格字符,但我不确定这是否是正确的方法。我也觉得我可以做出愚蠢的错误,比如==而不是=。这是我目前的代码

vector<Token> tokenize(wstring file)
{
    ifstream input = ifstream(file);
    vector<Token> tokens;

    while(input.peek() != std::char_traits<char>::eof())
    {
        wchar_t ch = (wchar_t) input.peek();

        if (isspace(ch)) 
        {
            input.get();
        }
        else if(ch == '[' || ch == ']')
        {
            input.get();
            wstring str(&ch);
            tokens.push_back(Token(SYMBOL, str));
        }
        else if (ch == '"') 
        { 
            wstringstream accum; 
            input.get();

            while(input.peek() != '"')
            {
                if(input.peek() == std::char_traits<char>::eof())
                    endProgram(L"Unterminated String Literal");

                accum<<input.peek();
                input.get();
            }

            tokens.push_back(Token(STRING, accum.str()));
        }
    }

    for(int i = 0; i < tokens.size(); i++)
    {
        wcout<<tokens.at(i).getData()<<endl;
    }

    return tokens;
}

然而,当我在像这样的文件上运行此代码时

] ]
"ddsd"

"sdsd"

[[]]]]][[

我得到了我的错误UnterminatedStringLiteral我做错了什么?我是c ++的新手,所以简单的解释会很好。

3 个答案:

答案 0 :(得分:0)

添加更多“令牌”时,您的代码可能会变得更复杂 我建议使用switch声明:

switch (ch)
{
    case '[':
        //...
        break;
    case ']':
        //...
        break;
// ...
    default:
        //...
        break;
};

或者使用带有函数指针的查找表:

  typedef (void)(*Function_Pointer_Type)(char ch);
  struct Lookup_Table_Entry
  {
     char   token;
     Function_Pointer_Type token_processor_func;
  };

  static const Lookup_Table_Entry  token_table[] =
  {
    { '[', Open_Bracket_Handler},
    { ']', Close_Bracket_Handler},
    { '\"', String_Delimiter},
  };
  static const unsigned int    token_table_size =
    sizeof(token_table) / sizeof(token_table[0]);

  //...
  for (unsigned int i = 0; i < token_table_size; ++i)
  {
     if (ch == token_table[i].token)
     {
        token_table[i].token_processor_func(ch);
        break;
     }
  }

这两个代码片段都更清晰,可以处理字符不是令牌的情况。

如果添加更多令牌,表查找可以更轻松地扩展代码。

答案 1 :(得分:0)

我制作了这样的代码..

  ///    if(*parm_data == ' ' || *parm_data == ';' || *parm_data == '|' 
     //   || *parm_data == '\t' || *parm_data == ',') break; 

        char *CHXLog::GetToken(char *parm_data, char *parm_token)
        {
            while(*parm_data != 0 && *parm_data != '\n')
            { 

                if( *parm_data == ',' )
                {       
                    break; 
                }
                else 
                {
                    *parm_token =*parm_data; 
                }
                parm_data++; 
                parm_token++; 
            } 

            *parm_token = '\0'; 

            return parm_data + 1; 

        }

答案 2 :(得分:0)

我在这段代码中想出了我的问题

        while(input.peek() != '"')
        {
            if(input.peek() == std::char_traits<char>::eof())
                endProgram(L"Unterminated String Literal");

            accum<<input.peek();
            input.get();
        }

        tokens.push_back(Token(STRING, accum.str()));

应该有一个

input.get();

跳过“角色