Большинством вещей, которые похожи на операторы, являются методы в Ruby; 1 + 2
синтаксический сахар для 1.+(2)
.
Даже при том, что +
и *
методы, которые может переопределить программа, Ruby имеет специальное волшебство оценить 1 + 2 * 3
как 1.+(2.*(3))
вместо 1.+(2).*(3)
.
Интересно, где это специальное волшебство живет в Ruby - если это соединено проводами в интерпретатор.
Ari.
Во всех реализациях Ruby, предшествование операторов обрабатывается парсером. Поскольку практически все существующие реализации Ruby используют один и тот же парсер, или парсер, созданный на основе одной и той же грамматики YACC, parse.y
в YARV - это тот файл, на который вы хотите посмотреть. (В JRuby, например, этот файл по сути такой же: src/org/jruby/parser/Ruby19Parser.y
. То же самое для IronRuby: Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Parser.y
.)
Единственные четыре реализации Ruby, которые не либо используют парсер YARV напрямую, либо используют клон YACC, сгенерированный из парсера YARV parse.y
, это Cardinal, tinyrb, RubyGoLightly и XRuby.
Cardinal - это реализация Ruby для виртуальной машины Parrot, и поскольку Parrot включает в себя Parrot Grammar Engine, Cardinal, естественно, использует его. Интересный файл - src/parser/grammar.pg
. PGE - это гибридный рекурсивно-дескриптивный парсер/парсер операторного предшествования, что означает, что операторное предшествование довольно хорошо проявляется в файле грамматики.
Tinyrb использует PEG парсер, использующий библиотеку leg Яна Пьюмарта. Как типично для PEG парсеров, здесь нет таблицы предшествования операторов, скорее предшествование подразумевается в иерархической структуре грамматики. Подробности см. в vm/grammar.leg
. RubyGoLightly является производной от tinyrb, только в качестве языка реализации используется Go, а не C, но используется та же грамматика PEG.
XRuby использует ANTLR для своего парсера. Здесь интересен файл src/com/xruby/compiler/parser/ruby.g
.
Rubinius использует парсер Melbourne, который по сути является парсером YARV, упакованным как расширение C. MagLev использует ruby_parser
(см. ниже).
Помимо реализаций Ruby, существуют и другие парсеры Ruby.
Ruby_parser Райана Дэвиса основан на грамматике YARV YACC. Он использует racc в качестве генератора парсера. See lib/ruby_parser.y
.
RedParse Калеба Клаузена использует собственноручно написанный компилятор-интерпретатор Калеба. Интересный файл - lib/redparse/babyparser.rb
.
Это все известные мне парсеры, которые действительно обрабатывают предшествование операторов. Есть еще один парсер, встроенный в RDoc, и раньше был один в YARD (сейчас он использует RedParse), но они обрабатывают только достаточное количество синтаксиса Ruby для поиска модулей, классов и методов, комментариев и извлечения списков параметров методов. Они не имеют дела с предшествованием операторов.
Да, это аппаратно, поэтому вы не можете добавлять новые операторы или изменять приоритет существующих операторов.
« Выражения операторов » в документации по языку дает таблицу с операторами, которые можно переопределить как методы. Вы не можете создавать свои собственные операторы - отображение операторов на их имена символов живет внутри анализатора.