J64_
offline
Опыт:
4,724Активность: |
Унарные операторы
Делая свой компилятор, я упоролся в отличии унарных от бинарных операторов: например, как отличить оператор ++a от ++a?
У меня в качестве базы данных есть map[тип1][строка][тип2]. Загвоздка в том, что я не знаю идущий за именем оператора тип (тип2). То есть, допустим, у нас есть входное выражение: <a + b>.
Конечно же можно извратиться путем просмотра следующего слова: идентификатор ли, вызов функции ли, константа ли или же открывающая скобка, но так синтаксис будет немного неудобен. Например нельзя будет вводит выражения типа <a + *(&b)>, а будет <a + (*(&(b)))>.
Наверное, ADOLF знаком с этим. Попрошу его ответить.
Пытался читать в википедии\книжке, искал в гугле, не понял - там не разжевано. Отредактировано ScorpioT1000, 22.07.2012 в 04:55. |
21.07.2012, 22:19 | #1
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
alexprey
познающий Unity
offline
Опыт:
68,501Активность: |
Judycaster64, делай не стек, а бинарное дерево для вычисления и т.д. По крайней мере я так делал у себя в интерпретаторе. |
22.07.2012, 01:40 | #2
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
Вы конченные, какой язык, ну да мб это было бы флудом при разработке межгалактического аннигилятора, но написат ьсвой язык намного сложнее, так вот мой вопрос, какого хрена свой язык, в понимаете, что творите ?
ScorpioT1000 добавил:
ну в целом идет a + b * c читаем токены
\n a + b * c \n читаем экспрешоны
a b c операторы op0 exp0 + exp1 op1 exp1 * exp2 приоритет 2 выполняем op1 выполняем op2 над временным результатом op1 ?
здесь проще говна, даже школьник решит, это я к тому, что забейте писать свой язык |
22.07.2012, 05:00 | #3
+0/−1
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
J64_
offline
Опыт:
4,724Активность: |
alexprey:
Возможно ты меня не понял или я тебя. Если ты имеешь в виду это: Вход: "2 + 2 + 2 * 5" ... a = 2; b = 5; op = *; node = new node (a, b, op); a = node; b = 2; op = "+"; node = new node(a, b, op); a = node; b = 2; op = "+"; node = new node(a, b, op); ... То да, я это делал. Суть не в этом. Короче, я не знаю сам приоритет оператора. Как я уже писал, он(сама целевая ссылка на экземпляр класса Type, который содержит приоритет, и прочую другую информацию) храниться в трехмерном map'е(map<Type*, map<string, map<Type*, Operator*>>> operatorMap, а это для того чтобы можно было добавлять свои операторы на ходу) нулевой индекс у нас известен - выталкиваем\берём из стека, первый это имя оператора, а вот что подать в качестве второго индекса?
ScorpioT1000
Почему ты всем говоришь что не надо делать то или иное? Что тогда нам делать? Карты создавать? Я тебя понял так: сначала читаем всё, и только потом сравниваем приоритеты.
И да, я делаю язык максимально похожий на С++. И вообще, у меня Напалеоновские планы. А всё для того чтобы сделать мапу для вк3. лол :3 |
22.07.2012, 07:36 | #4
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
alexprey
познающий Unity
offline
Опыт:
68,501Активность: |
Judycaster64:
А по другому и не сделаешь. Хотя у меня просто дерево строиться по приоритетам. То есть если приоритет такой же или ниже текущего нода, то вставляется в левое или в правое поддерево. Если приоритет выше текущего, то создается новый нод и к нему в левое поддерево вставляется текущий нод. Judycaster64:
Когда ты вручную строишь, ты же знаешь по каким приоритетам надо строить. Так вот и научи свой "компилятор" это сделать Judycaster64:
лол. Есть cJass, для мап вк3 |
22.07.2012, 11:21 | #5
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
J64_
offline
Опыт:
4,724Активность: |
alexprey:
Не знаю... короче, совсем запутался. Ты говоришь что нашёл приоритет, но не говоришь как. Ведь как ты говоришь у тебя там одноименных операторов нету, то есть у тебя приоритеты хранятся в чем-то вроде мэпа, в которой, строка(имя), выступает как индекс. Или как? спасибо за уведомление. |
22.07.2012, 12:10 | #6
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
alexprey
познающий Unity
offline
Опыт:
68,501Активность: |
Judycaster64, приоритеты записаны для каждого типа оператора |
22.07.2012, 14:51 | #7
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
J64_
offline
Опыт:
4,724Активность: |
alexprey: Да, записаны. Но как узнать? |
22.07.2012, 15:19 | #8
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
alexprey
познающий Unity
offline
Опыт:
68,501Активность: |
Judycaster64, ну так достать, где записаны. Ах да, у тебя унарные операторы. Ну вот смотри.
допустим построили дерево
Для выражения 1 + -2 Фактически унарные операторы имеют более высокий приоритет, чем бинарные. Как узнать что оператор именно унарный. Так просто. Во время построения дерева по токенам, у унарного оператора отсутствует левый операнд (левая часть поддерева). Ну вообще я руководствовался вроде такому принципу:
|
22.07.2012, 16:12 | #9
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Romeno
offline
Опыт:
3,167Активность: |
Я как то ковырялся с lex-ом и yacc-ом... для питона: PLY. Насколько я помню там проблема "двоякости" восприятия была решена. В документации, в главе 5. Parsing basics приведён пример того как ведёт себя парсер. Для такого обхода дерева даже есть какое то название, только не помню какое...
По-мойму в таких случаях лучше сконцентрироваться на написании правил к языку, поэтому, возможно, хотя бы для того чтобы быстрее получить первоначальный результат имеет смысл обратить внимание на сторонние лексические/семантические анализаторы типа лекса, яка и др... Ещё есть хорошая книжка, сам я её только немножко прочитал, но рекомендуется как must-have. Книга дракона Может это поможет... |
23.07.2012, 03:22 | #10
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
Когда я писал свой парсер, он сначала бил на лексемы (т.е. разбивка на такие куски по пробельным символам, которые могут быть int,float,string итд итп). Потом лексемы превращались в экспрешшоны, например три лексемы
превращались в экспрешшон-константу строку
или вот пример
понимала, что это
запись числа с плав. точкой, а не 1.8 плюс e20f, и таких мелочей овер 9000
дальше уже парсилось на блоки по { и }, ходило назад-вперед, составляло базу данных потихоньку, ну и в итоге был десериализованный код =)
ScorpioT1000 добавил:
офк у всех операторов должны быть приоритеты, причем операторы могут быть перегружены и тогда он от контекста (обычно типов) должен смотреть, что делать ScorpioT1000 добавил: т.е. что я хотел сказать что разные вещи решаются на разном уровне, сначала должен быть подход к кодировке и служебным символам, распознание чисел, бинарных строк ака "\24\28\r\n", систем счисления и неопределённостей на уровне лексера, только потом перейти к экспрешшенам Отредактировано ScorpioT1000, 23.07.2012 в 14:20. |
23.07.2012, 09:25 | #11
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|