Простой метод для простого парсера - PullRequest
4 голосов
/ 11 августа 2011

Я пытаюсь создать простой синтаксический анализатор и небольшой текстовый файл, который имеет следующую структуру :

Variable_name = Value;

VARIABLE_2 = SECOND_VALUE;

Найдены методы, которые работают , однако использует много библиотек , таких как Boost. Интересно, можно ли сделать простым, желательно только с библиотеками STD .

Спасибо, Бруно Алано.

Ответы [ 5 ]

3 голосов
/ 11 августа 2011

Если ваш формат останется таким же, как вы перечислили, и в именах переменных или значениях не будет пробелов, это можно легко сделать, используя комбинацию std::string и std::istringstream.Вы можете просто сделать следующее:

//assume we have an open ifstream object called in_file to your file
string line;
getline(in_file, line);

while (in_file.good())
{
    char variable[100];
    char value[100];
    char equals;

    //get rid of the semi-colon at the end of the line
    string temp_line = line.substr(0, line.find_last_of(";"));
    istringstream split_line(temp_line);

    //make sure to set the maximum width to prevent buffer overflows
    split_line >> setw(100) >> variable >> equals >> value;

    //do something with the string data in your buffers

    getline(in_file, line);
}

Вы можете изменить типы variable и value, чтобы они соответствовали вашим потребностям ... они не должны быть буферами char, номожет быть любого другого типа при условии, что istream& operator>>(istream&, type&) определено для типа данных, который вы хотите использовать.

3 голосов
/ 11 августа 2011

Если переменные и значения не могут содержать знаки равенства или точки с запятой, и вы можете предположить, что файл всегда будет правильно сформирован, это тривиально.

Захватывайте все, пока не достигните точки с запятой.Разбейте строку на знак =.Первая часть - это имя вашей переменной.Вторая часть - это значение.

Если вам приходится иметь дело с комментариями, строковыми литеральными значениями (которые могут содержать = или ;), это НЕПРИВОДНО , и вам следуетиспользуйте boost.Spirit.

Если вам интересно, как разбить строку, задают много вопросов по этой теме, и особенно хороший: Разделить строку в C ++?

1 голос
/ 11 августа 2011

Очень короткий (в стиле C) метод будет выглядеть примерно так:

scanf("%s = %[^\n]", variable_name, value);
1 голос
/ 11 августа 2011

Вы можете использовать генератор парсеров лимона , он генерирует файл без зависимостей, кроме stdlibc. Здесь - хорошее начальное руководство.

В качестве сканера я предпочитаю re2c , который также является общественным достоянием.

Вы можете обернуть yyparse() функция в классе C ++, если вам действительно нужен C ++.

1 голос
/ 11 августа 2011

Он в основном не отличается от INI-файла.

Быстрый поиск дает следующий результат: http://code.google.com/p/inih/

, который имеет минимальные зависимости.

Если вам нужно,Вероятно, довольно просто исключить обработку раздела.

Однако вам нужно добавить обработку точек с запятой, которые обычно являются началом комментариев в файлах INI.

ЭтоНачальная точка, по крайней мере.

...