Каким должен быть язык программирования? Анализ и критика Описание языка Компилятор
Отечественные разработки Cтатьи на компьютерные темы Компьютерный юмор Новости и прочее

Как отличить унарный минус от бинарного

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

Минус является унарным в следующих случаях:

  • если ему предшествует бинарная операция — как в непрерывной цепочке, так и отделённая пробельными символами
    x =- y
    m *= - n
    a <<< - n
    
  • после запятой
    (x, y, -z)	
    {1, -a, b}
    
  • после ключевого слова
    return —z
    if -w == v
    
  • лексема в строке — первая (после конца строки)
    x = (if x==y
        -a
    else
       -b)
    
  • лексема в выражении — первая
    х = а * (-b)
    z = c [-d]
    
Минус является бинарным в следующих случаях:
  • после идентификатора
    a = identifier - b
    
  • после числового литерала
    a = 2 - b
    
  • после закрывающей скобки
    y = f(x) - а
    z = m[n] - а
    

Последняя правка: 2018-10-29    15:54

ОценитеОценки посетителей
   ██████ 1 (14.2%)
   ▌ 0
   ██████ 1 (14.2%)
   ██████████████████████████████ 5 (71.4%)

Отзывы

     2016/06/03 04:34, rst256

лексема в строке — первая (после конца строки)
x = (if x==y
-a
else
-b)

это же Statement будет, а не expression! Распознается как бинарный ((х==у)-б), если без костыля с '\13', или как непонятно что (ибо выражению нечего делать в области Statement'ов, особенно если после if не используется then).

     2016/06/03 12:14, Автор сайта

Конец строки (точнее — «конец выражения») после условия должен быть обязательно. А конец строки — это либо 16"0d0a", либо точка с запятой. Приведённый пример можно оформить и так:
x = (if x==y; -a; else -b)

     2016/11/06 08:06, rst256

Вообще конкретно с операцией "-" достаточно того, что бинарный "-" может быть один и только в начале цепочки, постфиксной операции "--" ведь нет, префиксная не примет в качестве операнда результат от унарного "-" (---а), а двойное отрицание (- - а т.е. --а) очевидно и так не допустимо.

     2017/09/16 20:20, Comdiv

И тут непонятные усложнения в лексическом анализе. Минус — это минус, он не одиночный и не двоичный. Есть операции вычитания и смены знака, но минус они используют один и тот же. При желании можно вообще не выделять две операции при составлении грамматики:
Сумма = [ + ! - ] Слагаемое { ( + ! - ) Слагаемое } .
Лучше потренироваться на воплощении учебных языков прежде, чем думать о реализации основного.

     2017/09/16 23:30, Автор сайта

В С++ унарные «+» и «-» имеют приоритет 2. Бинарные же — приоритет 5. Понятно, что речь идёт о разных операциях. Соответственно их надо отличать. Можно это сделать на этапе лексического анализа, можно эту задачу отложить на потом. Как лучше? Лексический анализ всё-таки проще синтаксического. Поэтому, на мой взгляд, лучше утяжелить лексический анализ, облегчая и без того сложный синтаксический.

     2017/09/18 11:39, Comdiv

Здесь путаница операции и знака. Знак один и тот же, операции разные (или одинаковые, как в приведённой мною грамматике). Лексер выдаёт лексемы-знаки, парсер разбирает операции. Поскольку знак один и тот же, то и лексер должен выдавать одно и то же, а не мудрить. Речь не должна идти о том, что следует усложнить, потому что оно простое, а о том, что соответствует смыслу. Тогда общая сложность системы будет меньше. Именно это важно. Просто попробуйте на учебном языке и почувствуйте.

     2017/09/18 22:36, Автор сайта

Да, можно и попробовать и так, и сяк. А потом сравнить. Однако ж, если синтаксическому анализатору уже разжевали семантику минуса, разве это плохо?

     2017/09/20 02:00, Comdiv

Если работа уже сделана, то назад время, конечно, не вернуть. Если же нет, то можно упростить задачу. Но, может, Вы не ищете лёгких путей? Тогда можно и так.

     2018/05/28 18:34, Александр Коновалов aka Маздайщик

Автор сайта!

Кстати, да. Вы уже пробовали делать реализацию каких-нибудь мелких элементов входного языка чисто для проверки концепций? Не только back-end’а (про эксперименты с двумя стеками я знаю), но и front-end’а? Потому что можно написать, например, интерпретатор какого-нибудь подмножества и закодировать на нём простейшие алгоритмы (алгоритм Евклида, решение квадратных уравнений, сортировку пузырьком). И посмотреть, на сколько это удобно.

     2018/05/30 16:59, Автор сайта

Эксперименты на уровне лексем были. Но решил успокоить зуд и не тратить время на реализацию, пока язык не созрел в концепциях. Руки, конечно, чешутся, но программировать, а потом выкидывать наработанное в связи со сменой концепции — неразумно.

     2018/05/31 17:42, Comdiv

Так это называется прототипированием и оно вполне разумно.

     2018/09/29 10:01, utkin

Рассмотрите вариант — избавиться от унарного минуса. Для этого нужно считать это краткой записью операции с двумя параметрами:
-а эквивалентно 0 - а
И тогда никаких там кучи условий Вам не требуется, а реализация упрощается.

     2018/09/29 16:52, Автор сайта

Пожалуй, Вы правы, так вполне работоспособно. Правда, решение о классификации минуса будет перенесено на этап синтаксического анализа. А хотелось бы, чтобы об этом знал уже лексер. А так — почему бы и нет?

Но тут ещё надо иметь в виду, что могут быть и иные операции, которые могут быть и унарными, и бинарными. Помимо минуса в Си — это «*» «&», которые в бинарном варианте — умножение и арифметическое «и», а в унарном — обращение по адресу и получение адреса. Конечно, лучше, когда унарные и бинарные операции не пересекаются. Но для минуса этого не избежать, слишком велика живуча традиция использовать его в двух вариантах.

Написать отзыв

Написать автору можно на электронную почту mail(аt)compiler.su

Авторизация

Регистрация

Выслать пароль

Карта сайта


Каким должен быть язык программирования?

Анализ и критика

Описание языка

Компилятор

Надо ли использовать YACC, LEX и подобные инструменты

Выбор кодировки для компилятора

Раскрутка компилятора

Лексический анализатор

●  Разбор цепочек знаков операций

●  Как отличить унарный минус от бинарного

Отечественные разработки

Cтатьи на компьютерные темы

Компьютерный юмор

Новости и прочее

Последние комментарии

2018/12/16 17:17 ••• Геннадий Тышов
✎ Программирование без программистов — это медицина без врачей

2018/12/07 08:57 ••• Автор сайта
✎ Почему обречён язык Форт

2018/12/07 08:36 ••• Автор сайта
✎ Нужны ли беззнаковые целые?

2018/12/03 13:51 ••• kt
✎ Экстракоды при синтезе программ

2018/11/30 17:56 ••• Freeman
✎ Изменение приоритетов операций

2018/11/30 17:20 ••• Автор сайта
✎ Почему языки с синтаксисом Си популярнее языков с синтаксисом Паскаля?

2018/11/26 14:23 ••• Автор сайта
✎ Так ли нужны операции «&&», «||» и «^^»?

2018/11/18 15:21 ••• Freeman
✎ Устарел ли текст как форма представления программы

2018/11/17 03:28 ••• Comdiv
✎ Изменение длины объекта в стеке во время исполнения

2018/11/16 12:53 ••• Автор сайта
✎ Помеченные комментарии

2018/11/11 14:01 ••• Александр Коновалов aka Маздайщик
✎ Нерабочий код

2018/11/11 13:39 ••• Александр Коновалов aka Маздайщик
✎ О русском языке в программировании