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

Parse Simple Syntax with only Keyword and Number Extraction

本文关键字:简单 语法 提取 数字 关键字      更新时间:2023-10-16

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

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;
}

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

但是,上述实现被破坏了,因为使用此实现,我只能提取椅子而不是相关数字。怎么能做到这一点呢?我对正则表达式完全没有经验,所以我没有尝试。

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

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

一种简单、简单和好的方法,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你可以传递你的字符串。 就是这样。

试试这段代码

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

房间未找到!

按任意键继续 . . .