仅使用关键字和数字提取解析简单语法

时间:2017-02-08 16:23:52

标签: c++ token

所以我有一个简单的回车分离文件,内容如下:

room(800,400)
place(desk, 5, 6)
place(chair, 8, 5)
place(bed, 6, 6)
place(closet, 1, 4)

我试图存储每个关键字(桌子,椅子,床和衣柜)和相关的x,y的存在并存储在某处(不重要!)并提取room尺寸并再次存储在某处。我的代码如下:

#include <iostream>
#include <fstream>
#include <string>
using namepace std;

void Keyword(ifstream & stream, string token) {
    string line;
    while (getline(stream, line)) {
        if (line.find(token) != string::npos) {
            cout << line << endl;

            if(token == "room") {
                //store the numbers and string to somewhere
            }

            if (token == "table") {
                //store the numbers and string to somewhere
            }
        }
    }
    cout << token << " Not Found!" << endl;
}

int main()
{

    // Shape Grammar Parser  
    ifstream infile("shape.dat");

    Keyword(infile, "room");    
    return 0;
}

我想要做的是,当解析器看到place(chair, 8, 5)它存储在数据结构chair, 8, 5中时,或者当它看到空间时,它会提取room, 800, 400

然而,上述实现被打破,因为这个实现我只能提取主席而不是相关的数字。怎么办?我对正则表达式缺乏经验,所以我没有尝试过。

3 个答案:

答案 0 :(得分:2)

这里的逻辑是颠倒的。不是将令牌名称传递给Keyword(需要更好的名称; parse_file可能更具描述性),而只需Keyword即可调用istream&。让Keyword完成确定哪些令牌存在的工作:

while (get_line(stream, line)) {
    std::string::size_type pos = line.find('(');
    if (pos == std::string::npos)
        throw file_read_failure(); // user-defined exception type
    std::string token = line.substr(0, pos);
    if (token == "room")
        parse_room(line.substr(pos));
    else if (token == "table")
        parse_table(line.substr(pos));
    // et cetera

答案 1 :(得分:1)

简单明了的方式std::regex_iterator

std::basic_regex< char > regex ( "\\d+" );
std::string string = "place(closet, 1, 4)";

std::regex_iterator< std::string::iterator > first ( string.begin(), string.end(), regex );
std::regex_iterator< std::string::iterator > last;

while( first != last ){ std::cout << first->str() << ' '; ++first; }  

输出

1 4

而不是我写的string,你可以传递你的字符串。是的。

答案 2 :(得分:1)

试试这段代码

void Keyword(ifstream & stream, string token) {
    string line;

    int dimension1;
    int dimension2;
    string item_in_room;

    while (getline(stream, line,'(')) {

        if ( !line.compare("room") )
        {
            getline(stream, line,',');
            dimension1 = atoi( line.c_str() );

            getline(stream, line,')');
            dimension2 = atoi( line.c_str() );

            cout << "It's a room, dimensions: " << dimension1 << " , " << dimension2 << endl;
        }

        if ( !line.compare("place") )
        {
            getline(stream, item_in_room,',');

            getline(stream, line,',');
            dimension1 = atoi( line.c_str() );

            getline(stream, line,')');
            dimension2 = atoi( line.c_str() );

            cout << "It's a " << item_in_room << " dimensions: " << dimension1 << " , " << dimension2 << endl;
        }

        //read the rest of the line, just to get to a new new
        getline(stream, line);
    }
    cout << token << " Not Found!" << endl;
}

它有效,这是输出:

这是一个房间,尺寸:800,400

桌面尺寸:5,6

这是一把椅子尺寸:8,5

床尺寸:6,6

这是一个壁橱尺寸:1,4

找不到房间!

按任意键继续。 。