![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
rudvil |
|
||||||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 20.11.2009 Где: Latvia/Riga Репутация: 2 Всего: 3 |
Интересуют способы создания дерева из постфиксной записи, не простой-типа
А как обойтись с более сложными записями, например дана след. ebnf грамматика
и такой текст-парсеру
Сгенерированное дерево из этой записи(см. выше) должно быть таким ![]() Т.е. нужен универсальный способ(алгоритм?), что-бы при изменении грамматики-не пришлось бы переписывать что-либо в коде, для корректного генерирования абстрактного синтаксического дерева, спасибо. Это сообщение отредактировал(а) rudvil - 19.5.2010, 21:11 --------------------
xor |
||||||||
|
|||||||||
ИванМ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1260 Регистрация: 19.6.2006 Где: СПб Репутация: 1 Всего: 23 |
Вообще деревьями лучше не пользоваться. Постфиксная запись самодостаточная.
Также существуют стандартные библиотеки для работы с грамматиками. Например, boost::Spirit. Правда, с помощью него ошибки не проверить. Должен быть код изначально правильный. |
|||
|
||||
rudvil |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 20.11.2009 Где: Latvia/Riga Репутация: 2 Всего: 3 |
Т.е. выполнять код "на лету" из постфиксной записи быстрее, чем прогонять аналогичное дерево? На данный момент у меня готов лексер+парсер, т.е. проверить что эффективней пока-что не могу... з.ы. spirit'ом не пользуюсь - не понравился, слишком навороченный да и компилирует жуть как долго, поэтому использую самописный парсер. --------------------
xor |
|||
|
||||
ИванМ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1260 Регистрация: 19.6.2006 Где: СПб Репутация: 1 Всего: 23 |
rudvil, быстрее и с точки зрения выполнения, а особенно сточки зрения трансляции исходного кода. Для постфиксной записи достаточно одного прохода, а в случае с деревом - больше одного. К тому же в случае постфиксной записи памяти меньше расходуется и она динамически освобождается, что для дерева ни так.
|
|||
|
||||
GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
а что лучше, постфиксная запись, или префиксная запись? и вообще, в чем у них принципиальная разница?
|
|||
|
||||
ИванМ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1260 Регистрация: 19.6.2006 Где: СПб Репутация: 1 Всего: 23 |
С постфиксной удобнее работать. Например, выражение 1 + 2 в постфиксной записи: 1 2 + выполнение: 1->стек 2->cтек +: стек->x, стек->y, (x+y)->стек На выходе в стеке 3, как и положено в префиксной записи: + 1 2 такое быстро реализовать с помощью стека проблематично |
|||
|
||||
rudvil |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 20.11.2009 Где: Latvia/Riga Репутация: 2 Всего: 3 |
Спасибо за совет, а то я как зациклился над этим "деревом"... так всё и приостановилось - пока не нашел бы решения. Теперь смело продолжу разработку своего я.п. Ещё раз спасибо! --------------------
xor |
|||
|
||||
rudvil |
|
||||||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 20.11.2009 Где: Latvia/Riga Репутация: 2 Всего: 3 |
Рано я обрадовался, а как тогда все-же обойтись без дерева, если даны 3 простых выражения основанные на этой грамматики
и скормить парсеру
то мы, получим вот-что
запись так-сказать получается "снизу вверх", тогда как нужно выполнение выражений "сверху вниз" и это наблюдается везде, не только в выражениях, но и в конструкциях типа иф-елсе и.т.д. Одним проходом "на лету" никак не получится. Другое дело, дерево - там все было-бы разложено по местам и все становится понятным. Поэтому наверное вернусь к асд, пусть не так быстро , зато понятно что - к чему. все ещё акутально
Это сообщение отредактировал(а) rudvil - 20.5.2010, 09:33 --------------------
xor |
||||||||
|
|||||||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
PS. 1+2*3 - это не 'постфиксная запись', а инфиксная. Это сообщение отредактировал(а) xvr - 20.5.2010, 12:02 |
|||
|
||||
rudvil |
|
||||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 20.11.2009 Где: Latvia/Riga Репутация: 2 Всего: 3 |
генераторы.. уйй как не хочется их использовать ![]()
это я знаю, спасибо. Гугл облазил, есть только примеры бинарных деревьев для простых выражений... а если потомков может быть не 2, а 4 или 9 или... Есть идея пройтись разок по грамматики и создать список всех правил и какие подправила могут быть у текущего правила... т.е. если посмотреть на грамматику в первом посте, то для первых 2-ух правил можно создать след таблицу: std::map<std::string/*название правила*/, std::list<std::string>/*может содержать...*/ > table; 1-ое правило "translation_unit" может содержать в себе "func_def" и "declaration" 2-ое правило "func_def" содержит "name", "params_expr" и "func_body" т.е. то что в квадратных скобках... вот... и благодаря этой таблице создать из этого
![]() т.е. первое что мы видим это - "func_def" далее идет "func_body", если "func_body" может находиться в "func_def" то создаем дерево с корнем "func_def" и потомком "func_body" ну и далее обрабатываем похожим образом все оставшееся... конечно этот способ не идеален... но т.к. пока других вариантов не вижу - остановлюсь на нем. --------------------
xor |
||||||
|
|||||||
ИванМ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1260 Регистрация: 19.6.2006 Где: СПб Репутация: 1 Всего: 23 |
rudvil, тот пример, что вы привели, также можно реализовать с помощью постфиксной записи. И без деревьев. Просто нужно создать еще один дополнительный стек. Если надо, могу выслать один свой проект. Там с помощью постфиксной записи реализованы очень сложные вычисления: приоритет операций, условные операторы и проч..
|
|||
|
||||
rudvil |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 20.11.2009 Где: Latvia/Riga Репутация: 2 Всего: 3 |
После изучения примера mini_c в boost::spirit который "на лету" производит все операции и работает по такому же принципу как мне хотелось изначально, я пришел к выводу что мне это все-же не подходит.
Во первых, насколько я теперь понимаю - без дерева будет крайне неудобно проводить семантический анализ, а он уж точно мне будет нужен. Во вторых, я почитал как устроен питон и мне кажется что имеет смысл продвигаться в том же направлении, т.е. транслировать в упрощенный код и уже этот упрощенный код выполнять "на лету" ![]() --------------------
xor |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Если нужен какой то нетривиальный анализ (и возможно какие то оптимизации, или просто преобразования), то без дерева (или DAG) обойтись не получится (даже в теории)
|
|||
|
||||
rudvil |
|
||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 20.11.2009 Где: Latvia/Riga Репутация: 2 Всего: 3 |
Дабы не создавать новую тему спрошу тут, какие преимущества у меня будут если я буду использовать при динамическом парсинге, NFA/DFA вместо дерева.
Поясню насчет дерева, вот EBNF грамматика
Понятно что у питона парсер статический т.е. сгенерированный. Но т.к. я хочу использовать динамический парсинг, хотелось бы узнать - что будет эффективней? Динамически генерируемое дерево или динамически генерируемые NFA/DFA?, и естественно последующий парсинг... Это сообщение отредактировал(а) rudvil - 15.6.2010, 13:50 --------------------
xor |
||||
|
|||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
NFA/DFA не заменят стекового парсера (LL1/LR1/LALR1/etc) - это разный класс граматик.
Например ваша грамматика в NFA/DFA не ляжет. NFA/DFA описывают класс грамматик, соотвествующий регулярным выражениям. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |