structNode
{
string nodeName;
StringList variables;
}
[C++] Парсер переменных в структурах
Есть текстовый файл с описанием переменных, которые могут быть как простого типа с определенным размером, так и структурами. Структуры могут быть вложенными. В общем, полная аналогия struct c++. В итоге нужно получить "линейный" список всех переменных простого типа со смещением адреса. Причем их имена должны полными, т.е. включая имя структуры, например <Структура1.ВложеннаяСтруктура2.Переменная>.
Уперся в то, что не могу определиться, как лучше хранить полученные переменные при разборе? Напрашивается что-то типа дерева.
Для разбора синтаксиса файла уже использую boost::regex, смотрел на Boost Graph Library, там есть реализация tree, но что-то сложновато, может, нужно совсем не то?
Можно использовать стек, например.
Когда входиш в очередную структуру заталкиваеш ее имя в стек (разумеется тогда стек типа стринг), когда доходишь до простого типа, береш имя переменой, и добавляешь в свой линейный список строку. то есть стек читаеш со дна и до количества элементов в нем и в конце приписываеш имя переменной. После того как дошел до конца вложено структуры выталкиваеш последнюю из стека и продолжаеш дальше
Код:
struct Type1
{
int i1;
bool b1;
};
struct Type2
{
bool b;
Type1 x; //Вложенная структура
int i;
};
//Переменные, которые нужно преобразовать к линейному массиву
//простых типов со смещением адресов
int i1; //адрес 0.0
bool b3; //адрес 4.0
bool b4; //адрес 4.1
int i2; //адрес 6.0
Type1 tp1;
//tp1 в линейном массиве раскладывается на:
//int tp1.i1; //адрес 10.0
//bool tp1.b1; //адрес 14.0
bool b5; //адрес 16.0 (из-за двухбайтового выравнивания)
Type2 tp2;
//tp2 в линейном массиве раскладывается на:
//bool tp2.b; //адрес 18.0
//int tp2.x.i1; //адрес 20.0
//и т.д.
{
int i1;
bool b1;
};
struct Type2
{
bool b;
Type1 x; //Вложенная структура
int i;
};
//Переменные, которые нужно преобразовать к линейному массиву
//простых типов со смещением адресов
int i1; //адрес 0.0
bool b3; //адрес 4.0
bool b4; //адрес 4.1
int i2; //адрес 6.0
Type1 tp1;
//tp1 в линейном массиве раскладывается на:
//int tp1.i1; //адрес 10.0
//bool tp1.b1; //адрес 14.0
bool b5; //адрес 16.0 (из-за двухбайтового выравнивания)
Type2 tp2;
//tp2 в линейном массиве раскладывается на:
//bool tp2.b; //адрес 18.0
//int tp2.x.i1; //адрес 20.0
//и т.д.
Еще тут добавляется условие двухбайтового выравнивания. Вот между булевскими переменными b3 и b4 разрыва нет, а между tp1.b1 и b5 есть, хотя они тоже идут последовательно. Просто в последнем случае закончилась структура и необходимо выравнивание.
Что-то непонятно, в файле будут только описания структур или только экземпляры структур с переменными или и описание структур, и экземпляры структур, и просто переменные?
Цитата: Alm3n
...и описание структур, и экземпляры структур, и просто переменные
Именно так. То есть точно так как в примере, который я привел, только синтаксис будет другим, но это не важно.
Код:
Где по каждая нода - это элемент списка. Когда встречаешь название структуры, записываешь его в nodeName, а все переменные, которые в ней есть, добавляешь в variables. Потом, когда будешь извлекать из основной очереди(или стека) имена переменных, будет просто достать из такого объекта нужные данные. Написать только для него несколько методов: добавления, удаления ноды и поиска ноды по имени структуры. Как-то так.
хм, а тут помоему уже стек не зачем, если не нужно парсить сами структуры. Сначало заносиш кудато описание своих структур, например в список, предложеный Alm3n. Потом нужна переменная - для хранения смещения, после того как обработал очередную переменную, увеличаваеш смещения на нужное количество байт, если это был байт увеличиваеш сразу на 2. А теперь как формировать список переменных. Делаешь процедру которая проверяет или найденная лексема простой тип, если да добавляет в линейный список, если нет то ищет в очереди структуру с именем это лексемы и вызывает рекурсивно себя, тоесть теперь мы разбираем переменные внутри структуры, если опять найдем вложенную мы войдем в нее еще глубже. Условия возврата - конец списка переменных.