Каким должен быть язык программирования? Анализ и критика Описание языка Компилятор
Отечественные разработки 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] - а
    

Опубликовано: 2016.06.01, последняя правка: 2018.10.29    15:54

ОценитеОценки посетителей
   ███████████████ 9 (34.6%)
   ████ 2 (7.69%)
   ███████ 4 (15.3%)
   ██████████████████ 11 (42.3%)

Отзывы

     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татьи на компьютерные темы

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

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




Последние отзывы

2024/03/28 21:36 ••• Ivan
Энтузиасты-разработчики компиляторов и их проекты

2024/03/27 19:12 ••• MihalNik
Постфиксные инкремент и декремент

2024/03/22 20:41 ••• void
Раскрутка компилятора

2024/03/20 19:54 ••• kt
О многократном резервировании функций

2024/03/20 13:13 ••• Неслучайный читатель
Надёжные программы из ненадёжных компонентов

2024/03/10 18:33 ••• Бурановский дедушка
Русской операционной системой должна стать ReactOS

2024/03/07 14:16 ••• Неслучайный читатель
«Двухмерный» синтаксис Python

2024/03/03 16:49 ••• Автор сайта
О неправомерном доступе к памяти через указатели

2024/02/28 18:59 ••• Вежливый Лис
Про лебедей, раков и щук

2024/02/24 18:10 ••• Бурановский дедушка
ЕС ЭВМ — это измена, трусость и обман?

2024/02/22 15:57 ••• Автор сайта
Русский язык и программирование

2024/02/19 17:58 ••• Сорок Сороков
О русском языке в программировании

2024/02/16 16:33 ••• Клихальт
Избранные компьютерные анекдоты