0

我正在用 C++ 编写一个标记器。它要做的是在文件中搜索包含在“”中的字符串字符以及符号 [ 和 ]。它将为其创建一个标记对象,并将其存储在一个向量中。它应该通过调用 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++ 的新手,所以一个简单的解释会很好。

4

3 回答 3

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; 

        }
于 2013-10-28T01:21:44.023 回答
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();

跳过 " 字符

于 2013-10-28T19:46:21.833 回答
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;
     }
  }

这两个代码片段都更干净,可以处理字符不是标记的情况。

如果添加更多标记,则表查找允许更轻松地扩展代码。

于 2013-10-28T00:12:48.700 回答