2010-02-13 13 views
7

Большинство вещей, которые выглядят как операторы, - это методы в Ruby; 1 + 2 - синтаксический сахар для 1.+(2).Операторы и методы в Ruby

Даже если + и * методы, которые могут переопределить программа, Ruby имеет особую магию, чтобы оценить, как 1 + 2 * 31.+(2.*(3)) вместо 1.+(2).*(3).

Интересно, где эта особая магия живет в Ruby - если она сложна в интерпретаторе.

Ari.

ответ

10

Во всех реализациях Ruby оператор Приоритет обрабатывается парсером. Поскольку почти все существующие Ruby-реализации используют один и тот же синтаксический анализатор или парсер, созданный из одной грамматики YACC, parse.y in YARV is the file you want to look at. (В JRuby, например, что файл является по существу то же самое:. src/org/jruby/parser/Ruby19Parser.y же для IronRuby:. Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Parser.y)

Единственные четыре Рубиновые Реализации, которые делают не либо использовать YARV анализатор непосредственно или использовать YACC клон сгенерированный анализатор от YARV's parse.y, являются Cardinal, tinyrb, RubyGoLightly и XRuby.

Cardinal - это реализация Ruby для виртуальной машины Parrot, и поскольку Parrot включает в себя движок грамматики Parrot, кардинал, естественно, использует это. Интересный файл: src/parser/grammar.pg. PGE - это парсер синтаксического анализатора парсера/оператора с гибридным рекурсивным спусканием, что означает, что приоритет оператора довольно хорошо проявляется в файле грамматики.

Tinyrb использует парсер PEG, используя библиотеку ножек Яна Пиумарта. Как это типично для парсеров PEG, нет таблицы приоритетов операторов, а приоритет неявна в иерархической структуре грамматики. См. vm/grammar.leg. RubyGoLightly получен из tinyrb, за исключением того, что вместо него используется язык Go вместо C как язык реализации, но он использует ту же грамматику PEG.

XRuby использует ANTLR для анализатора. Здесь интересный файл: src/com/xruby/compiler/parser/ruby.g.

Рубиний использует парсер Мельбурна, который по сути является парсером YARV, упакованным как расширение C. MagLev использует ruby_parser (см. Ниже).

Помимо рубиновых реализаций, есть и другие анализаторы Ruby.

Ryan Davis's ruby_parser получен из грамматики YARV YACC. Он использует racc в качестве генератора парсера. См. lib/ruby_parser.y.

RedParse Caleb Clausen использует собственный ручной интерпретатор Caleb. Интересный файл: lib/redparse/babyparser.rb.

Вот и все парсеры, которые я знаю, которые фактически обрабатывают приоритет оператора.В RDoc есть еще один парсер, и раньше в YARD использовался один (он теперь использует RedParse), но они обрабатывают достаточно синтаксиса Ruby для поиска модулей, классов и методов, комментариев и списков параметров метода извлечения. Они не имеют дело с приоритетом оператора.

+0

Спасибо. Ваш ответ очень подробный и имеет отличные указатели на файлы, включая номера строк. Это значительно превышает мои ожидания. Я искал некоторые из ваших других ответов и много узнал о реализации Ruby. Спасибо, что поделились своими знаниями. – iter

+0

Добро пожаловать! –

0

Да, это сложно, поэтому вы не можете добавлять новых операторов или изменять приоритет существующих операторов.

2

«Operator Expressions» в документации на языке приводится таблица с операторами, которые могут быть переопределены как методы. Вы не можете создавать свои собственные операторы - отображение операторов в имена их символов живет внутри анализатора.

+0

Благодарим вас за ссылку - я знаком с ней и должен был включить ее в вопрос. Я ищу более конкретный ответ, чем «предположительно, живет внутри парсера». Возможно, я могу это сформулировать так: если бы я хотел разблокировать свою собственную версию Ruby, где '*' имел более низкий приоритет, чем '+', какие файлы я бы изменил. Ari. – iter