SlideShare a Scribd company logo
1 of 54
Download to read offline
Hacking parse.y
Tatsuhiro Ujihisa
ujihisa@gmail.com
http://ujihisa.blogspot.com/
@ujm
hi
•I'm from Japan
DISCLAIMER
•This presentation is
not for super rubyists
or ruby committers,
but for ordinary
programmers.
Hacking parse.y
•Ruby's syntax
Hacking parse.y
Fixing ruby parser to understand ruby
•Introducing new syntax
• {:key :-) "value"}
• 'symbol
• ++i
• def A#b(c)
• {|x| x * 2 }
MRI Inside
•MRI (Matz Ruby Implementation)
•$ ruby -v
ruby 1.9.2dev (2009-11-19 trunk 25862) [i386-darwin9.8.0]
•Written in C
•array.c, vm.c, gc.c, etc...
ruby 1.8 vs 1.9
•~1.8
• Parser: parse.y
• Evaluator: eval.c
•1.9~
• Parser: parse.y
• Evaluator:YARV (vm*.c)
Matz said
•Ugly: eval.c and parse.y
RubyConf2006
•Now the original evaluator
was all replaced withYARV
MRI Parser
•MRI uses yacc
(parser generator for C)
•parse.y
bison -d -o y.tab.c parse.y
sed -f ./tool/ytab.sed -e "/^#/s!y.tab.c!
parse.c!" y.tab.c > parse.c.new
...
parse.y
•One of the darkest side
•$ wc -l *{c,h,y} | sort -n
...
9961 io.c
10474 parse.y
16367 parse.c # (automatically generated)
188656 total
(Broad) Parser
•Lexer (yylex)
•Bytes → Symbols
•Parser (yyparse)
•Symbols → Syntax Tree
Tokens in Lexer
%token tUPLUS /* unary+ */
%token tUMINUS /* unary- */
%token tPOW /* ** */
%token tCMP /* <=> */
%token tEQ /* == */
%token tEQQ /* === */
%token tNEQ /* != */
%token tGEQ /* >= */
%token tLEQ /* <= */
%token tANDOP tOROP /* && and || */
%token tMATCH tNMATCH/* =~ and !~ */
%token tDOT2 tDOT3 /* .. and ... */
%token tAREF tASET /* [] and []= */
%token tLSHFT tRSHFT /* << and >> */
%token tCOLON2 /* :: */
%token tCOLON3 /* :: at EXPR_BEG */
%token <id> tOP_ASGN /* +=, -= et
%token tASSOC /* => */
%token tLPAREN /* ( */
%token tLPAREN_ARG /* ( */
%token tRPAREN /* ) */
%token tLBRACK /* [ */
%token tLBRACE /* { */
%token tLBRACE_ARG /* { */
%token tSTAR /* * */
%token tAMPER /* & */
%token tLAMBDA /* -> */
%token tSYMBEG tSTRING_BEG tXSTRING_
tWORDS_BEG tQWORDS_BEG
%token tSTRING_DBEG tSTRING_DVAR tST
(detour)
n MRI: parse.y (10474 lines)
n JRuby: src/org/jruby/{parser, lexer}/* (24983 lines)
n parser/DefaultRubyParser.y (1880 lines)
parser/Ruby19Parser.y (2076 lines)
n Rubinius: lib/ext/melbourne/grammer.y (5891 lines)
and others
Case 1:
:-)
•Hash literal
{:key => 'value'}
{:key :-) 'value'}
•:-) is just an alias of =>
Mastering “Colon”
Colons in Ruby
•A::B, ::C
•:symbol, :"sy-m-bol"
•a ? b : c
•{a: b}
•when 1: something (in 1.8)
static int
parser_yylex(struct parser_params *parser) {
...
switch (c = nextc()) {
...
case '#': /* it's a comment */
...
case ':':
c = nextc();
if (c == ':') {
if (IS_BEG() ||...
...
}
... (about 1300 lines)
How does parser deal
with colon?
•:: → tCOLON2 or tCOLON3
•tCOLON2 Net::URI
•tCOLON3 ::Kernel
enum lex_state_e {
EXPR_BEG, /* ignore newline, +/- is a sign. */
EXPR_END, /* newline significant, +/- is an operator. *
EXPR_ENDARG, /* ditto, and unbound braces. */
EXPR_ARG, /* newline significant, +/- is an operator. *
EXPR_CMDARG, /* newline significant, +/- is an operator. *
EXPR_MID, /* newline significant, +/- is an operator. *
EXPR_FNAME, /* ignore newline, no reserved words. */
EXPR_DOT, /* right after `.' or `::', no reserved words
EXPR_CLASS, /* immediate after `class', no here document.
EXPR_VALUE /* alike EXPR_BEG but label is disallowed. */
};
lex_state
case ':':
c = nextc();
if (c == ':') {
if (IS_BEG() ||
lex_state == EXPR_CLASS ||
(IS_ARG() && space_seen)) {
lex_state = EXPR_BEG;
return tCOLON3;
}
lex_state = EXPR_DOT;
return tCOLON2;
}
...
if (lex_state == EXPR_END ||
lex_state == EXPR_ENDARG ||
(c != -1 && ISSPACE(c))) {
pushback(c);
lex_state = EXPR_BEG;
return ':';
}
switch (c) {
case ''':
lex_strterm = NEW_STRTERM(str_ssym, c, 0);
break;
case '"':
lex_strterm = NEW_STRTERM(str_dsym, c, 0);
break;
default:
pushback(c);
break;
}
lex_state = EXPR_FNAME;
return tSYMBEG;
How does parser deal
with colon? (summary)
•:: → tCOLON2 or tCOLON3
•EXPR_END or →: (else)
•otherwise → tSYMBEG
•:' → str_ssym
•:" → str_dsym
So,
•:-) → tASSOC
•:: → tCOLON2 or tCOLON3
•EXPR_END or →: (else)
•otherwise → tSYMBEG
•:' → str_ssym
•:" → str_dsym
:-)
DISCLAIMER
•This presentation is
not for super rubyists
or ruby committers,
but for ordinary
programmers.
Case 2:
Lisp Like Symbol
•Symbol Literal
:vancouver
'vancouver
•Ad-hoc
p :a, :b
p 'a, 'b
Single Quote
(in parser_yylex)
...
case ''':
lex_strterm = NEW_STRTERM(str_squote, ''', 0);
return tSTRING_BEG;
...
Single Quote
(in parser_yylex)
...
case ''':
if (??? condition ???) {
lex_state = EXPR_FNAME;
return tSYMBEG;
}
lex_strterm = NEW_STRTERM(str_squote, ''', 0);
return tSTRING_BEG;
...
(loop
(lambda (p 'good)))
Case3: Pre
Incremental Operator
•++i
•i = i.succ
(NOT i = i + 1)
Lexer
@@ -685,6 +685,7 @@ static void
token_info_pop(struct parser_params*, const
char *token);
%type <val> program reswords then do
dot_or_colon
%*/
%token tUPLUS /* unary+ */
+%token tINCR /* ++var */
%token tUMINUS /* unary- */
%token tPOW /* ** */
%token tCMP /* <=> */
(Actually there are more trivial fixes)
regenerate id.h
•id.h is automatically
generated by parse.y in make
•$ rm id.h
$ make
parser example
variable : tIDENTIFIER
| tIVAR
| tGVAR
| tCONSTANT
| tCVAR
| keyword_nil {ifndef_ripper($$ = keyword_nil);}
| keyword_self {ifndef_ripper($$ = keyword_self);}
| keyword_true {ifndef_ripper($$ = keyword_true);}
| keyword_false {ifndef_ripper($$ = keyword_false);}
| keyword__FILE__ {ifndef_ripper($$ = keyword__FILE__);}
| keyword__LINE__ {ifndef_ripper($$ = keyword__LINE__);}
| keyword__ENCODING__ {ifndef_ripper($$ = keyword__ENCODING_
;
lhs : variable
{
/*%%%*/
if (!($$ = assignable($1, 0))) $$ = NEW_BEGIN(0);
/*%
$$ = dispatch1(var_field, $1);
%*/
}
| primary_value '[' opt_call_args rbracket
{
/*%%%*/
$$ = aryset($1, $3);
/*%
$$ = dispatch2(aref_field, $1, escape_Qundef($3));
%*/
}
...
BNF (part)
program : compstmt
compstmt : stmts opt_terms
stmts : none
| stmt
| stmts terms stmt
stmt : kALIAS fitem fitem
| kALIAS tGVAR tGVAR
:
:
| expr
expr : kRETURN call_args
| kBREAK call_args
:
:
| '!' command_call
| arg
arg : lhs '=' arg
| var_lhs tOP_ASGN arg
| primary_value '[' aref_args ']' tOP
:
:
| arg '?' arg ':' arg
| primary
primary : literal
| strings
:
:
| tLPAREN_ARG expr ')'
| tLPAREN compstmt ')'
:
:
| kREDO
| kRETRY
Assign
stmt : ...
| mlhs '=' command_call
{
/*%%%*/
value_expr($3);
$1->nd_value = $3;
$$ = $1;
/*%
$$ = dispatch2(massign, $1, $3);
%*/
}
mlhs
mlhs: mlhs_basic | ...
mlhs_basic: mlhs_head | ...
mlhs_head: mlhs_item ',' | ...
mlhs_item: mlhs_node | ...
mlhs_node: variable {
$$ = assignable($1, 0); }
Method call
block_command : block_call
| block_call '.' operation2 command_args
{
/*%%%*/
$$ = NEW_CALL($1, $3, $4);
/*%
$$ = dispatch3(call, $1, ripper_id2sym('.'),
$$ = method_arg($$, $4);
%*/
}
Mix!
var_ref: ...
| tINCR variable
{
/*%%%*/
$$ = assignable($2, 0);
$$->nd_value = NEW_CALL(gettable($$->nd_vid),
rb_intern("succ"), 0);
/*%
$$ = dispatch2(unary, ripper_intern("++@"), $2);
%*/
}
++ruby
Case 4:
def A#b
•A#b
instance method b of class A
•A.b
class method b of class A
A#b
class A
def b
...
end
end
def A.b
...
end
A#b
def A#b
...
end
def A.b
...
end
#
(in parser_yylex)
case '#': /* it's a comment */
/* no magic_comment in shebang line */
if (!parser_magic_comment(parser, lex_p, lex_pend - lex_p)) {
if (comment_at_top(parser)) {
set_file_encoding(parser, lex_p, lex_pend);
}
}
lex_p = lex_pend;
#
(in parser_yylex)
case '#': /* it's a comment */
c = nextc();
pushback(c);
if(lex_state == EXPR_END && ISALNUM(c)) return '#';
/* no magic_comment in shebang line */
if (!parser_magic_comment(parser, lex_p, lex_pend - lex_p)) {
if (comment_at_top(parser)) {
set_file_encoding(parser, lex_p, lex_pend);
Primary
primary: literal | ...
| k_def singleton dot_or_colon {lex_state = EXPR_FNAME;} fname
{
in_single++;
lex_state = EXPR_END; /* force for args */
/*%%%*/
local_push(0);
/*%
%*/
}
f_arglist
bodystmt
k_end
{
/*%%%*/
NODE *body = remove_begin($8);
reduce_nodes(&body);
$$ = NEW_DEFS($2, $5, $7, body);
fixpos($$, $2);
local_pop();
/*%
$$ = dispatch5(defs, $2, $3, $5, $7, $8);
%*/
in_single--;
}
| k_def cname '#' {lex_state = EXPR_FNAME;} fname
{
$<id>$ = cur_mid;
cur_mid = $5;
in_def++;
/*%%%*/
local_push(0);
/*%
%*/
}
f_arglist
bodystmt
k_end
{
/*%%%*/
NODE *body = remove_begin($8);
reduce_nodes(&body);
$$ = NEW_DEFN($5, $7, body, NOEX_PRIVATE);
fixpos($$, $7);
fixpos($$->nd_defn, $7);
$$ = NEW_CLASS(NEW_COLON3($2), $$, 0);
nd_set_line($$, $<num>6);
local_pop();
/*%
$$ = dispatch4(defi, $2, $5, $7, $8);
%*/
in_def--;
cur_mid = $<id>6;
}
Reference
Rubyソースコード完全解説
青木峰郎 著、まつもとゆ
きひろ 監修
Minero AOKI,Yukihiro
MATSUMOTO
"Ruby Hacking Guide"
HTMLVersion is available
Reference
•My blog
http://ujihisa.blogspot.com
•All patches I showed are there
end
Appendix:
Imaginary Numbers
•Matz wrote a patch in
[ruby-dev:38843]
•translation:
[ruby-core:24730]
•It won't be accepted
Appendix:
Imaginary Numbers
> 3i
=> (0 + 3i)
> 3i.class
=> Complex
Appendix
•{you <3 ruby}
•f(x, y) = z
(like f[x, y] = z as f.[]=(x, y, z))
•Annotations!

More Related Content

What's hot

Lexical environment in ecma 262 5
Lexical environment in ecma 262 5Lexical environment in ecma 262 5
Lexical environment in ecma 262 5Kim Hunmin
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовYandex
 
C++totural file
C++totural fileC++totural file
C++totural filehalaisumit
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Platonov Sergey
 
Swiftの関数型っぽい部分
Swiftの関数型っぽい部分Swiftの関数型っぽい部分
Swiftの関数型っぽい部分bob_is_strange
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itSergey Platonov
 
Study of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proramStudy of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proramMeenakshi Devi
 
Javascript & Ajax Basics
Javascript & Ajax BasicsJavascript & Ajax Basics
Javascript & Ajax BasicsRichard Paul
 
Алексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляАлексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляSergey Platonov
 
AnyObject – 自分が見落としていた、基本の話
AnyObject – 自分が見落としていた、基本の話AnyObject – 自分が見落としていた、基本の話
AnyObject – 自分が見落としていた、基本の話Tomohiro Kumagai
 
Rust Mozlando Tutorial
Rust Mozlando TutorialRust Mozlando Tutorial
Rust Mozlando Tutorialnikomatsakis
 
Rust concurrency tutorial 2015 12-02
Rust concurrency tutorial 2015 12-02Rust concurrency tutorial 2015 12-02
Rust concurrency tutorial 2015 12-02nikomatsakis
 
Kamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil Witecki
 
Chainer-Compiler 動かしてみた
Chainer-Compiler 動かしてみたChainer-Compiler 動かしてみた
Chainer-Compiler 動かしてみたAkira Maruoka
 

What's hot (20)

C++ idioms.pptx
C++ idioms.pptxC++ idioms.pptx
C++ idioms.pptx
 
Rust-lang
Rust-langRust-lang
Rust-lang
 
Lexical environment in ecma 262 5
Lexical environment in ecma 262 5Lexical environment in ecma 262 5
Lexical environment in ecma 262 5
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
 
MFC Message Handling
MFC Message HandlingMFC Message Handling
MFC Message Handling
 
C++ tutorial
C++ tutorialC++ tutorial
C++ tutorial
 
C++totural file
C++totural fileC++totural file
C++totural file
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.
 
Swiftの関数型っぽい部分
Swiftの関数型っぽい部分Swiftの関数型っぽい部分
Swiftの関数型っぽい部分
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
 
"let ECMAScript = 6"
"let ECMAScript = 6" "let ECMAScript = 6"
"let ECMAScript = 6"
 
Study of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proramStudy of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proram
 
Javascript & Ajax Basics
Javascript & Ajax BasicsJavascript & Ajax Basics
Javascript & Ajax Basics
 
Алексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляАлексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуля
 
AnyObject – 自分が見落としていた、基本の話
AnyObject – 自分が見落としていた、基本の話AnyObject – 自分が見落としていた、基本の話
AnyObject – 自分が見落としていた、基本の話
 
Rust Mozlando Tutorial
Rust Mozlando TutorialRust Mozlando Tutorial
Rust Mozlando Tutorial
 
Clang tidy
Clang tidyClang tidy
Clang tidy
 
Rust concurrency tutorial 2015 12-02
Rust concurrency tutorial 2015 12-02Rust concurrency tutorial 2015 12-02
Rust concurrency tutorial 2015 12-02
 
Kamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, code
 
Chainer-Compiler 動かしてみた
Chainer-Compiler 動かしてみたChainer-Compiler 動かしてみた
Chainer-Compiler 動かしてみた
 

Viewers also liked

Exploiting JRuby: Building Domain-Specific Languages for the Java Virtual Mac...
Exploiting JRuby: Building Domain-Specific Languages for the Java Virtual Mac...Exploiting JRuby: Building Domain-Specific Languages for the Java Virtual Mac...
Exploiting JRuby: Building Domain-Specific Languages for the Java Virtual Mac...elliando dias
 
The elephant in the room mongo db + hadoop
The elephant in the room  mongo db + hadoopThe elephant in the room  mongo db + hadoop
The elephant in the room mongo db + hadoopiammutex
 
MongoDB Advanced Topics
MongoDB Advanced TopicsMongoDB Advanced Topics
MongoDB Advanced TopicsCésar Rodas
 
Bitter Java, Sweeten with JRuby
Bitter Java, Sweeten with JRubyBitter Java, Sweeten with JRuby
Bitter Java, Sweeten with JRubyBrian Sam-Bodden
 
Indexing and Query Optimizer (Richard Kreuter)
Indexing and Query Optimizer (Richard Kreuter)Indexing and Query Optimizer (Richard Kreuter)
Indexing and Query Optimizer (Richard Kreuter)MongoDB
 

Viewers also liked (6)

Exploiting JRuby: Building Domain-Specific Languages for the Java Virtual Mac...
Exploiting JRuby: Building Domain-Specific Languages for the Java Virtual Mac...Exploiting JRuby: Building Domain-Specific Languages for the Java Virtual Mac...
Exploiting JRuby: Building Domain-Specific Languages for the Java Virtual Mac...
 
The elephant in the room mongo db + hadoop
The elephant in the room  mongo db + hadoopThe elephant in the room  mongo db + hadoop
The elephant in the room mongo db + hadoop
 
Trabalho
Trabalho Trabalho
Trabalho
 
MongoDB Advanced Topics
MongoDB Advanced TopicsMongoDB Advanced Topics
MongoDB Advanced Topics
 
Bitter Java, Sweeten with JRuby
Bitter Java, Sweeten with JRubyBitter Java, Sweeten with JRuby
Bitter Java, Sweeten with JRuby
 
Indexing and Query Optimizer (Richard Kreuter)
Indexing and Query Optimizer (Richard Kreuter)Indexing and Query Optimizer (Richard Kreuter)
Indexing and Query Optimizer (Richard Kreuter)
 

Similar to Hacking parse.y to understand new Ruby syntax

Best C++ Programming Homework Help
Best C++ Programming Homework HelpBest C++ Programming Homework Help
Best C++ Programming Homework HelpC++ Homework Help
 
Basic c++ 11/14 for python programmers
Basic c++ 11/14 for python programmersBasic c++ 11/14 for python programmers
Basic c++ 11/14 for python programmersJen Yee Hong
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Introzhang tao
 
Unit 4
Unit 4Unit 4
Unit 4siddr
 
D Trace Support In My Sql Guide To Solving Reallife Performance Problems
D Trace Support In My Sql Guide To Solving Reallife Performance ProblemsD Trace Support In My Sql Guide To Solving Reallife Performance Problems
D Trace Support In My Sql Guide To Solving Reallife Performance ProblemsMySQLConference
 
Quick tour of PHP from inside
Quick tour of PHP from insideQuick tour of PHP from inside
Quick tour of PHP from insidejulien pauli
 
Angular Weekend
Angular WeekendAngular Weekend
Angular WeekendTroy Miles
 
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2PVS-Studio
 
Sergi Álvarez & Roi Martín - Radare2 Preview [RootedCON 2010]
Sergi Álvarez & Roi Martín - Radare2 Preview [RootedCON 2010]Sergi Álvarez & Roi Martín - Radare2 Preview [RootedCON 2010]
Sergi Álvarez & Roi Martín - Radare2 Preview [RootedCON 2010]RootedCON
 
Debugging Ruby Systems
Debugging Ruby SystemsDebugging Ruby Systems
Debugging Ruby SystemsEngine Yard
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2rubyMarc Chung
 
The Ring programming language version 1.7 book - Part 83 of 196
The Ring programming language version 1.7 book - Part 83 of 196The Ring programming language version 1.7 book - Part 83 of 196
The Ring programming language version 1.7 book - Part 83 of 196Mahmoud Samir Fayed
 
06 -working_with_strings
06  -working_with_strings06  -working_with_strings
06 -working_with_stringsHector Garzo
 
Function Call Optimization
Function Call OptimizationFunction Call Optimization
Function Call Optimizationppd1961
 

Similar to Hacking parse.y to understand new Ruby syntax (20)

Meta Object Protocols
Meta Object ProtocolsMeta Object Protocols
Meta Object Protocols
 
Best C++ Programming Homework Help
Best C++ Programming Homework HelpBest C++ Programming Homework Help
Best C++ Programming Homework Help
 
Basic c++ 11/14 for python programmers
Basic c++ 11/14 for python programmersBasic c++ 11/14 for python programmers
Basic c++ 11/14 for python programmers
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Intro
 
Unit 4
Unit 4Unit 4
Unit 4
 
Boosting Developer Productivity with Clang
Boosting Developer Productivity with ClangBoosting Developer Productivity with Clang
Boosting Developer Productivity with Clang
 
Ruby 1.9
Ruby 1.9Ruby 1.9
Ruby 1.9
 
D Trace Support In My Sql Guide To Solving Reallife Performance Problems
D Trace Support In My Sql Guide To Solving Reallife Performance ProblemsD Trace Support In My Sql Guide To Solving Reallife Performance Problems
D Trace Support In My Sql Guide To Solving Reallife Performance Problems
 
Quick tour of PHP from inside
Quick tour of PHP from insideQuick tour of PHP from inside
Quick tour of PHP from inside
 
Angular Weekend
Angular WeekendAngular Weekend
Angular Weekend
 
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
 
Sergi Álvarez & Roi Martín - Radare2 Preview [RootedCON 2010]
Sergi Álvarez & Roi Martín - Radare2 Preview [RootedCON 2010]Sergi Álvarez & Roi Martín - Radare2 Preview [RootedCON 2010]
Sergi Álvarez & Roi Martín - Radare2 Preview [RootedCON 2010]
 
Tork03 LT
Tork03 LT Tork03 LT
Tork03 LT
 
Groovy
GroovyGroovy
Groovy
 
Debugging Ruby Systems
Debugging Ruby SystemsDebugging Ruby Systems
Debugging Ruby Systems
 
Stop Monkeys Fall
Stop Monkeys FallStop Monkeys Fall
Stop Monkeys Fall
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
 
The Ring programming language version 1.7 book - Part 83 of 196
The Ring programming language version 1.7 book - Part 83 of 196The Ring programming language version 1.7 book - Part 83 of 196
The Ring programming language version 1.7 book - Part 83 of 196
 
06 -working_with_strings
06  -working_with_strings06  -working_with_strings
06 -working_with_strings
 
Function Call Optimization
Function Call OptimizationFunction Call Optimization
Function Call Optimization
 

More from ujihisa

vimconf2013
vimconf2013vimconf2013
vimconf2013ujihisa
 
KOF2013 Minecraft / Clojure
KOF2013 Minecraft / ClojureKOF2013 Minecraft / Clojure
KOF2013 Minecraft / Clojureujihisa
 
Keynote ujihisa.vim#2
Keynote ujihisa.vim#2Keynote ujihisa.vim#2
Keynote ujihisa.vim#2ujihisa
 
vimshell made other shells legacy
vimshell made other shells legacyvimshell made other shells legacy
vimshell made other shells legacyujihisa
 
From Ruby to Haskell (Kansai Yami RubyKaigi)
From Ruby to Haskell (Kansai Yami RubyKaigi)From Ruby to Haskell (Kansai Yami RubyKaigi)
From Ruby to Haskell (Kansai Yami RubyKaigi)ujihisa
 
Text Manipulation with/without Parsec
Text Manipulation with/without ParsecText Manipulation with/without Parsec
Text Manipulation with/without Parsecujihisa
 
CoffeeScript in hootsuite
CoffeeScript in hootsuiteCoffeeScript in hootsuite
CoffeeScript in hootsuiteujihisa
 
HootSuite Dev 2
HootSuite Dev 2HootSuite Dev 2
HootSuite Dev 2ujihisa
 
Ruby Kansai49
Ruby Kansai49Ruby Kansai49
Ruby Kansai49ujihisa
 
Hootsuite dev 2011
Hootsuite dev 2011Hootsuite dev 2011
Hootsuite dev 2011ujihisa
 
LLVM Workshop Osaka Umeda, Japan
LLVM Workshop Osaka Umeda, JapanLLVM Workshop Osaka Umeda, Japan
LLVM Workshop Osaka Umeda, Japanujihisa
 
RubyConf 2009 LT "Termtter"
RubyConf 2009 LT "Termtter"RubyConf 2009 LT "Termtter"
RubyConf 2009 LT "Termtter"ujihisa
 
Ruby Kansai #35 About RubyKaigi2009 ujihisa
Ruby Kansai #35 About RubyKaigi2009 ujihisaRuby Kansai #35 About RubyKaigi2009 ujihisa
Ruby Kansai #35 About RubyKaigi2009 ujihisaujihisa
 
Kof2008 Itll
Kof2008 ItllKof2008 Itll
Kof2008 Itllujihisa
 
All About Metarw -- VimM#2
All About Metarw -- VimM#2All About Metarw -- VimM#2
All About Metarw -- VimM#2ujihisa
 
Itc2008 Ujihisa
Itc2008 UjihisaItc2008 Ujihisa
Itc2008 Ujihisaujihisa
 
Agile Web Posting With Ruby / Ruby Kaigi2008
Agile Web Posting With Ruby / Ruby Kaigi2008Agile Web Posting With Ruby / Ruby Kaigi2008
Agile Web Posting With Ruby / Ruby Kaigi2008ujihisa
 
Agile Web Posting with Ruby (lang:ja)
Agile Web Posting with Ruby (lang:ja)Agile Web Posting with Ruby (lang:ja)
Agile Web Posting with Ruby (lang:ja)ujihisa
 
From Java To Haskell P
From Java To Haskell PFrom Java To Haskell P
From Java To Haskell Pujihisa
 
Ruby Monad
Ruby MonadRuby Monad
Ruby Monadujihisa
 

More from ujihisa (20)

vimconf2013
vimconf2013vimconf2013
vimconf2013
 
KOF2013 Minecraft / Clojure
KOF2013 Minecraft / ClojureKOF2013 Minecraft / Clojure
KOF2013 Minecraft / Clojure
 
Keynote ujihisa.vim#2
Keynote ujihisa.vim#2Keynote ujihisa.vim#2
Keynote ujihisa.vim#2
 
vimshell made other shells legacy
vimshell made other shells legacyvimshell made other shells legacy
vimshell made other shells legacy
 
From Ruby to Haskell (Kansai Yami RubyKaigi)
From Ruby to Haskell (Kansai Yami RubyKaigi)From Ruby to Haskell (Kansai Yami RubyKaigi)
From Ruby to Haskell (Kansai Yami RubyKaigi)
 
Text Manipulation with/without Parsec
Text Manipulation with/without ParsecText Manipulation with/without Parsec
Text Manipulation with/without Parsec
 
CoffeeScript in hootsuite
CoffeeScript in hootsuiteCoffeeScript in hootsuite
CoffeeScript in hootsuite
 
HootSuite Dev 2
HootSuite Dev 2HootSuite Dev 2
HootSuite Dev 2
 
Ruby Kansai49
Ruby Kansai49Ruby Kansai49
Ruby Kansai49
 
Hootsuite dev 2011
Hootsuite dev 2011Hootsuite dev 2011
Hootsuite dev 2011
 
LLVM Workshop Osaka Umeda, Japan
LLVM Workshop Osaka Umeda, JapanLLVM Workshop Osaka Umeda, Japan
LLVM Workshop Osaka Umeda, Japan
 
RubyConf 2009 LT "Termtter"
RubyConf 2009 LT "Termtter"RubyConf 2009 LT "Termtter"
RubyConf 2009 LT "Termtter"
 
Ruby Kansai #35 About RubyKaigi2009 ujihisa
Ruby Kansai #35 About RubyKaigi2009 ujihisaRuby Kansai #35 About RubyKaigi2009 ujihisa
Ruby Kansai #35 About RubyKaigi2009 ujihisa
 
Kof2008 Itll
Kof2008 ItllKof2008 Itll
Kof2008 Itll
 
All About Metarw -- VimM#2
All About Metarw -- VimM#2All About Metarw -- VimM#2
All About Metarw -- VimM#2
 
Itc2008 Ujihisa
Itc2008 UjihisaItc2008 Ujihisa
Itc2008 Ujihisa
 
Agile Web Posting With Ruby / Ruby Kaigi2008
Agile Web Posting With Ruby / Ruby Kaigi2008Agile Web Posting With Ruby / Ruby Kaigi2008
Agile Web Posting With Ruby / Ruby Kaigi2008
 
Agile Web Posting with Ruby (lang:ja)
Agile Web Posting with Ruby (lang:ja)Agile Web Posting with Ruby (lang:ja)
Agile Web Posting with Ruby (lang:ja)
 
From Java To Haskell P
From Java To Haskell PFrom Java To Haskell P
From Java To Haskell P
 
Ruby Monad
Ruby MonadRuby Monad
Ruby Monad
 

Recently uploaded

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 

Recently uploaded (20)

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 

Hacking parse.y to understand new Ruby syntax

  • 3. DISCLAIMER •This presentation is not for super rubyists or ruby committers, but for ordinary programmers.
  • 5. Hacking parse.y Fixing ruby parser to understand ruby •Introducing new syntax • {:key :-) "value"} • 'symbol • ++i • def A#b(c) • {|x| x * 2 }
  • 6. MRI Inside •MRI (Matz Ruby Implementation) •$ ruby -v ruby 1.9.2dev (2009-11-19 trunk 25862) [i386-darwin9.8.0] •Written in C •array.c, vm.c, gc.c, etc...
  • 7. ruby 1.8 vs 1.9 •~1.8 • Parser: parse.y • Evaluator: eval.c •1.9~ • Parser: parse.y • Evaluator:YARV (vm*.c)
  • 8. Matz said •Ugly: eval.c and parse.y RubyConf2006 •Now the original evaluator was all replaced withYARV
  • 9. MRI Parser •MRI uses yacc (parser generator for C) •parse.y bison -d -o y.tab.c parse.y sed -f ./tool/ytab.sed -e "/^#/s!y.tab.c! parse.c!" y.tab.c > parse.c.new ...
  • 10. parse.y •One of the darkest side •$ wc -l *{c,h,y} | sort -n ... 9961 io.c 10474 parse.y 16367 parse.c # (automatically generated) 188656 total
  • 11. (Broad) Parser •Lexer (yylex) •Bytes → Symbols •Parser (yyparse) •Symbols → Syntax Tree
  • 12. Tokens in Lexer %token tUPLUS /* unary+ */ %token tUMINUS /* unary- */ %token tPOW /* ** */ %token tCMP /* <=> */ %token tEQ /* == */ %token tEQQ /* === */ %token tNEQ /* != */ %token tGEQ /* >= */ %token tLEQ /* <= */ %token tANDOP tOROP /* && and || */ %token tMATCH tNMATCH/* =~ and !~ */ %token tDOT2 tDOT3 /* .. and ... */ %token tAREF tASET /* [] and []= */ %token tLSHFT tRSHFT /* << and >> */ %token tCOLON2 /* :: */ %token tCOLON3 /* :: at EXPR_BEG */ %token <id> tOP_ASGN /* +=, -= et %token tASSOC /* => */ %token tLPAREN /* ( */ %token tLPAREN_ARG /* ( */ %token tRPAREN /* ) */ %token tLBRACK /* [ */ %token tLBRACE /* { */ %token tLBRACE_ARG /* { */ %token tSTAR /* * */ %token tAMPER /* & */ %token tLAMBDA /* -> */ %token tSYMBEG tSTRING_BEG tXSTRING_ tWORDS_BEG tQWORDS_BEG %token tSTRING_DBEG tSTRING_DVAR tST
  • 13. (detour) n MRI: parse.y (10474 lines) n JRuby: src/org/jruby/{parser, lexer}/* (24983 lines) n parser/DefaultRubyParser.y (1880 lines) parser/Ruby19Parser.y (2076 lines) n Rubinius: lib/ext/melbourne/grammer.y (5891 lines) and others
  • 14. Case 1: :-) •Hash literal {:key => 'value'} {:key :-) 'value'} •:-) is just an alias of =>
  • 16. Colons in Ruby •A::B, ::C •:symbol, :"sy-m-bol" •a ? b : c •{a: b} •when 1: something (in 1.8)
  • 17. static int parser_yylex(struct parser_params *parser) { ... switch (c = nextc()) { ... case '#': /* it's a comment */ ... case ':': c = nextc(); if (c == ':') { if (IS_BEG() ||... ... } ... (about 1300 lines)
  • 18. How does parser deal with colon? •:: → tCOLON2 or tCOLON3 •tCOLON2 Net::URI •tCOLON3 ::Kernel
  • 19. enum lex_state_e { EXPR_BEG, /* ignore newline, +/- is a sign. */ EXPR_END, /* newline significant, +/- is an operator. * EXPR_ENDARG, /* ditto, and unbound braces. */ EXPR_ARG, /* newline significant, +/- is an operator. * EXPR_CMDARG, /* newline significant, +/- is an operator. * EXPR_MID, /* newline significant, +/- is an operator. * EXPR_FNAME, /* ignore newline, no reserved words. */ EXPR_DOT, /* right after `.' or `::', no reserved words EXPR_CLASS, /* immediate after `class', no here document. EXPR_VALUE /* alike EXPR_BEG but label is disallowed. */ }; lex_state
  • 20. case ':': c = nextc(); if (c == ':') { if (IS_BEG() || lex_state == EXPR_CLASS || (IS_ARG() && space_seen)) { lex_state = EXPR_BEG; return tCOLON3; } lex_state = EXPR_DOT; return tCOLON2; }
  • 21. ... if (lex_state == EXPR_END || lex_state == EXPR_ENDARG || (c != -1 && ISSPACE(c))) { pushback(c); lex_state = EXPR_BEG; return ':'; } switch (c) { case ''': lex_strterm = NEW_STRTERM(str_ssym, c, 0); break; case '"': lex_strterm = NEW_STRTERM(str_dsym, c, 0); break; default: pushback(c); break; } lex_state = EXPR_FNAME; return tSYMBEG;
  • 22. How does parser deal with colon? (summary) •:: → tCOLON2 or tCOLON3 •EXPR_END or →: (else) •otherwise → tSYMBEG •:' → str_ssym •:" → str_dsym
  • 23. So, •:-) → tASSOC •:: → tCOLON2 or tCOLON3 •EXPR_END or →: (else) •otherwise → tSYMBEG •:' → str_ssym •:" → str_dsym
  • 24. :-)
  • 25. DISCLAIMER •This presentation is not for super rubyists or ruby committers, but for ordinary programmers.
  • 26. Case 2: Lisp Like Symbol •Symbol Literal :vancouver 'vancouver •Ad-hoc p :a, :b p 'a, 'b
  • 27. Single Quote (in parser_yylex) ... case ''': lex_strterm = NEW_STRTERM(str_squote, ''', 0); return tSTRING_BEG; ...
  • 28. Single Quote (in parser_yylex) ... case ''': if (??? condition ???) { lex_state = EXPR_FNAME; return tSYMBEG; } lex_strterm = NEW_STRTERM(str_squote, ''', 0); return tSTRING_BEG; ...
  • 31. Lexer @@ -685,6 +685,7 @@ static void token_info_pop(struct parser_params*, const char *token); %type <val> program reswords then do dot_or_colon %*/ %token tUPLUS /* unary+ */ +%token tINCR /* ++var */ %token tUMINUS /* unary- */ %token tPOW /* ** */ %token tCMP /* <=> */ (Actually there are more trivial fixes)
  • 32. regenerate id.h •id.h is automatically generated by parse.y in make •$ rm id.h $ make
  • 33. parser example variable : tIDENTIFIER | tIVAR | tGVAR | tCONSTANT | tCVAR | keyword_nil {ifndef_ripper($$ = keyword_nil);} | keyword_self {ifndef_ripper($$ = keyword_self);} | keyword_true {ifndef_ripper($$ = keyword_true);} | keyword_false {ifndef_ripper($$ = keyword_false);} | keyword__FILE__ {ifndef_ripper($$ = keyword__FILE__);} | keyword__LINE__ {ifndef_ripper($$ = keyword__LINE__);} | keyword__ENCODING__ {ifndef_ripper($$ = keyword__ENCODING_ ;
  • 34. lhs : variable { /*%%%*/ if (!($$ = assignable($1, 0))) $$ = NEW_BEGIN(0); /*% $$ = dispatch1(var_field, $1); %*/ } | primary_value '[' opt_call_args rbracket { /*%%%*/ $$ = aryset($1, $3); /*% $$ = dispatch2(aref_field, $1, escape_Qundef($3)); %*/ } ...
  • 35. BNF (part) program : compstmt compstmt : stmts opt_terms stmts : none | stmt | stmts terms stmt stmt : kALIAS fitem fitem | kALIAS tGVAR tGVAR : : | expr expr : kRETURN call_args | kBREAK call_args : : | '!' command_call | arg arg : lhs '=' arg | var_lhs tOP_ASGN arg | primary_value '[' aref_args ']' tOP : : | arg '?' arg ':' arg | primary primary : literal | strings : : | tLPAREN_ARG expr ')' | tLPAREN compstmt ')' : : | kREDO | kRETRY
  • 36. Assign stmt : ... | mlhs '=' command_call { /*%%%*/ value_expr($3); $1->nd_value = $3; $$ = $1; /*% $$ = dispatch2(massign, $1, $3); %*/ }
  • 37. mlhs mlhs: mlhs_basic | ... mlhs_basic: mlhs_head | ... mlhs_head: mlhs_item ',' | ... mlhs_item: mlhs_node | ... mlhs_node: variable { $$ = assignable($1, 0); }
  • 38. Method call block_command : block_call | block_call '.' operation2 command_args { /*%%%*/ $$ = NEW_CALL($1, $3, $4); /*% $$ = dispatch3(call, $1, ripper_id2sym('.'), $$ = method_arg($$, $4); %*/ }
  • 39. Mix! var_ref: ... | tINCR variable { /*%%%*/ $$ = assignable($2, 0); $$->nd_value = NEW_CALL(gettable($$->nd_vid), rb_intern("succ"), 0); /*% $$ = dispatch2(unary, ripper_intern("++@"), $2); %*/ }
  • 41. Case 4: def A#b •A#b instance method b of class A •A.b class method b of class A
  • 44. # (in parser_yylex) case '#': /* it's a comment */ /* no magic_comment in shebang line */ if (!parser_magic_comment(parser, lex_p, lex_pend - lex_p)) { if (comment_at_top(parser)) { set_file_encoding(parser, lex_p, lex_pend); } } lex_p = lex_pend;
  • 45. # (in parser_yylex) case '#': /* it's a comment */ c = nextc(); pushback(c); if(lex_state == EXPR_END && ISALNUM(c)) return '#'; /* no magic_comment in shebang line */ if (!parser_magic_comment(parser, lex_p, lex_pend - lex_p)) { if (comment_at_top(parser)) { set_file_encoding(parser, lex_p, lex_pend);
  • 46. Primary primary: literal | ... | k_def singleton dot_or_colon {lex_state = EXPR_FNAME;} fname { in_single++; lex_state = EXPR_END; /* force for args */ /*%%%*/ local_push(0); /*% %*/ } f_arglist bodystmt k_end { /*%%%*/ NODE *body = remove_begin($8); reduce_nodes(&body); $$ = NEW_DEFS($2, $5, $7, body); fixpos($$, $2); local_pop(); /*% $$ = dispatch5(defs, $2, $3, $5, $7, $8); %*/ in_single--; }
  • 47. | k_def cname '#' {lex_state = EXPR_FNAME;} fname { $<id>$ = cur_mid; cur_mid = $5; in_def++; /*%%%*/ local_push(0); /*% %*/ } f_arglist bodystmt k_end { /*%%%*/ NODE *body = remove_begin($8); reduce_nodes(&body); $$ = NEW_DEFN($5, $7, body, NOEX_PRIVATE); fixpos($$, $7); fixpos($$->nd_defn, $7); $$ = NEW_CLASS(NEW_COLON3($2), $$, 0); nd_set_line($$, $<num>6); local_pop(); /*% $$ = dispatch4(defi, $2, $5, $7, $8); %*/ in_def--; cur_mid = $<id>6; }
  • 48.
  • 49. Reference Rubyソースコード完全解説 青木峰郎 著、まつもとゆ きひろ 監修 Minero AOKI,Yukihiro MATSUMOTO "Ruby Hacking Guide" HTMLVersion is available
  • 51. end
  • 52. Appendix: Imaginary Numbers •Matz wrote a patch in [ruby-dev:38843] •translation: [ruby-core:24730] •It won't be accepted
  • 53. Appendix: Imaginary Numbers > 3i => (0 + 3i) > 3i.class => Complex
  • 54. Appendix •{you <3 ruby} •f(x, y) = z (like f[x, y] = z as f.[]=(x, y, z)) •Annotations!