SlideShare a Scribd company logo
1 of 26
Ruby
       Masaya TARUI
•
•
• tokyu.rb   #ruby-ja
•
•   Regexp
•   Rex

•   PEG ( Treetop , Citrus , Parslet )
•   Ripper
•   Bootstrap
•   M17N
•   ERB
•   Racc
•

•
•

•
• Racc
  strscan        Ruby


            C
                → Rex
Rex
•            C

•                           Regexp!

•                                                      Ruby



    /(match1)|(match2)|.../

                                  Marshal
                 capture
    [ match1,match1’s capture1, match1’s capture2...
•   Cature                                                Capture
                           1.9


                                                         Lost
                                                         Ruby parsec
•        tork05              (          tork03 )

•   @kawabata                       PEG                : Parsing Expression

    Grammar


    https://github.com/kawabata/aozora-proc

•
•   Ruby                         M17N                         Treetop,
    Citrus
    →(Rule           Class                         )

•             M17N
PEG

•
• Packrat Parser         O(n)
    Packrat Parser =

•
# -*- coding: utf-8 -*-
require 'pp'
require './peg.rb'

expr_peg = <<'EOT'
parser expr(top)
   top ← Expr !. ->$1
   Expr ← Sum
   Sum ← Product (('+' / '-') Product)* -> { restruct(r) }
   Product ← Value (('*' / '/') Value)* -> { restruct(r) }
   Value ← Sp n:[0-9]+ Sp -> {n.join.to_i}
        / Sp '(' e:Expr ')' Sp -> e
   Sp ← ( " " / "t" / "n" )*
EOT
def restruct(r)
 r[1].inject(r[0]){|a,b| [b[0],a,b[1]] }
end

expr_parser = PEG::ParserGenerator.parse(expr_peg)
require 'pp'

expr = " 1+ 2 * (3 - 4) / 5 + 6 "
pp expr
pp expr_parser.parse(expr)


=>
" 1+ 2 * (3 - 4) / 5 + 6 "
["+", ["+", 1, ["/", ["*", 2, ["-", 3, 4]], 5]], 6]




StackOverFlow                                                orz
PEG
•          PEG




•   M17N



           OK
-> { restruct(r) }



• Ruby
  → Ruby
parse.y
$ wc parse.y
    10745 27247 234392 parse.y




•
Ruby Scanner




   parse   “a <%= ‘%%>’ %>b”
-> { restruct(r) }

•   Ruby
    → Ruby

•
                     8
                10
ERB Ruby Scanner
    class TrimScanner < Scanner # :nodoc:
     def initialize(src, trim_mode, percent)

      super

      @trim_mode = trim_mode

      @percent = percent

      if @trim_mode == '>'

        @scan_line = self.method(:trim_line1)

      elsif @trim_mode == '<>'

        @scan_line = self.method(:trim_line2)

      elsif @trim_mode == '-'

        @scan_line = self.method(:explicit_trim_line)

      else

        @scan_line = self.method(:scan_line)

      end
     end
     attr_accessor :stag

     def scan(&block)

     @stag = nil

     if @percent

       @src.each_line do |line|

         percent_line(line, &block)

       end

     else
        @scan_line.call(@src, &block)

     end

     nil
     end

     def percent_line(line, &block)

     if @stag || line[0] != ?%

       return @scan_line.call(line, &block)

     end


     line[0] = ''

     if line[0] == ?%

       @scan_line.call(line, &block)

     else
        yield(PercentLine.new(line.chomp))

     end
     end
def trim_line2(line)

     head = nil
      line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>n|%>|n|z)/m) do |tokens|
        tokens.each do |token|
         next if token.empty?
         head = token unless head




    ERB Ruby Scanner
         if token == "%>n"
           yield('%>')
           if is_erb_stag?(head)
             yield(:cr)
           else
             yield("n")
           end
           head = nil
         else
           yield(token)
           head = nil if token == "n"
         end
        end

     end
     end

     def explicit_trim_line(line)
      line.scan(/(.*?)(^[ t]*<%-|<%-|<%%|%%>|<%=|<%#|<%|-%>n|-%>|%>|z)/m) do |tokens|
        tokens.each do |token|
         next if token.empty?
         if @stag.nil? && /[ t]*<%-/ =~ token
           yield('<%')
         elsif @stag && token == "-%>n"
           yield('%>')
           yield(:cr)
         elsif @stag && token == '-%>'
           yield('%>')
         else
           yield(token)
         end
        end
      end
     end

   ERB_STAG = %w(<%= <%# <%)
   def is_erb_stag?(s)

   ERB_STAG.member?(s)
   end
  end

    Scanner.default_scanner = TrimScanner




                                    Scanner
Racc                                Ruby Scanner
def scan_action
  buf = ''
    nest = 1
    pre = nil
    @in_block = 'action'
    begin
      pre = nil
      if s = reads(/As+/)
        # does not set 'pre'
        buf << s
      end
      until @line.empty?
        if s = reads(/A[^'"`{}%#/$]+/)
           buf << (pre = s)
           next
        end
        case ch = read(1)
        when '{'
           nest += 1
           buf << (pre = ch)
        when '}'
           nest -= 1
           if nest == 0
             @in_block = nil
             return buf
           end
           buf << (pre = ch)
        when '#'     # comment
           buf << ch << @line
           break
        when "'", '"', '`'
           buf << (pre = scan_quoted(ch))
        when '%'
           if literal_head? pre, @line
             # % string, regexp, array
             buf << ch
             case ch = read(1)
             when /[qQx]/n
                buf << ch << (pre = scan_quoted(read(1), '%string'))
             when /wW/n
# % string, regexp, array
           buf << ch
           case ch = read(1)
           when /[qQx]/n
             buf << ch << (pre = scan_quoted(read(1), '%string'))




Racc                             Ruby Scanner
           when /wW/n
             buf << ch << (pre = scan_quoted(read(1), '%array'))
           when /s/n
             buf << ch << (pre = scan_quoted(read(1), '%symbol'))
           when /r/n
             buf << ch << (pre = scan_quoted(read(1), '%regexp'))
           when /[a-zA-Z0-9= ]/n   # does not include "_"
             scan_error! "unknown type of % literal '%#{ch}'"
           else
             buf << (pre = scan_quoted(ch, '%string'))
           end
        else
           # operator
           buf << '||op->' if $raccs_print_type
           buf << (pre = ch)
        end
      when '/'
        if literal_head? pre, @line
           # regexp
           buf << (pre = scan_quoted(ch, 'regexp'))
        else
           # operator
           buf << '||op->' if $raccs_print_type
           buf << (pre = ch)
        end
      when '$'    # gvar
        buf << ch << (pre = read(1))
      else
        raise 'racc: fatal: must not happen'
      end
    end
    buf << "n"
  end while next_line()
  raise 'racc: fatal: scan finished before parser finished'
end
•
Ripper!
• parse.y          1.9              Ruby



•

irb(main):001:0> Ripper.parse("a = b + 1")
=> nil
Ripper

• test/ripper/test_files.rb
class Parser < Ripper
  PARSER_EVENTS.each {|n| eval "def on_#{n}(*args) r = [:#{n}, *args]; r.inspect; Object.new end" }
  SCANNER_EVENTS.each {|n| eval "def on_#{n}(*args) r = [:#{n}, *args]; r.inspect; Object.new end" }
end




•
Ripper                                                                          Scanner
     class RubyCodeDetector < Ripper
      class ParseError < Exception
        attr_reader :message,:result
        def initialize(r,msg)
         @result = r
         @message = msg
        end
      end
      def   on_parse_error(msg)
 
          l = @lines[lineno-1][0,column-1]
 
          src = (@lines[0,lineno-1]+[l])*"n"
 
          src.force_encoding(@src.encoding)
 
          raise ParseError.new(src,msg)
   end
   def initialize(*args)
    @src=args[0]
 
      @lines=@src.split(/n/).map{|i| i.force_encoding("ASCII-8BIT") }
    super
   end
   def parse
    super
    raise ParseError.new(@src,"syntax error, unexpected $end, expecting '}'")
    nil
   rescue ParseError => e

       if e.message =~ /G   syntax error, unexpected '}'/
         e.result
       else
         raise $!
         nil
       end
      end
     end
Ripper                                                                          Scanner
     class RubyCodeDetector < Ripper
      class ParseError < Exception
        attr_reader :message,:result
        def initialize(r,msg)
         @result = r
         @message = msg
        end
      end
      def   on_parse_error(msg)
 
          l = @lines[lineno-1][0,column-1]
 
          src = (@lines[0,lineno-1]+[l])*"n"
 
          src.force_encoding(@src.encoding)
 
          raise ParseError.new(src,msg)
   end
   def initialize(*args)
    @src=args[0]
 
      @lines=@src.split(/n/).map{|i| i.force_encoding("ASCII-8BIT") }
    super
   end
   def parse
    super
    raise ParseError.new(@src,"syntax error, unexpected $end, expecting '}'")
    nil
   rescue ParseError => e

       if e.message =~ /G   syntax error, unexpected '}'/
         e.result
       else
         raise $!
         nil
       end
      end
     end
•   Regexp
•   Rex

•   PEG ( Treetop , Citrus , Parslet )
•   Ripper
•   Bootstrap
•   M17N
•   ERB
•   Racc
• Ripper   1.9

• Ripper

More Related Content

What's hot

Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaPatrick Allaert
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Workhorse Computing
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPGuilherme Blanco
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machinejulien pauli
 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalKent Ohashi
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMsunng87
 
typemap in Perl/XS
typemap in Perl/XS  typemap in Perl/XS
typemap in Perl/XS charsbar
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Workhorse Computing
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Lin Yo-An
 
Function Call Optimization
Function Call OptimizationFunction Call Optimization
Function Call Optimizationppd1961
 
Yapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed PerlYapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed PerlHideaki Ohno
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)Nikita Popov
 
Oral presentation v2
Oral presentation v2Oral presentation v2
Oral presentation v2Yeqi He
 
Groovy on the Shell
Groovy on the ShellGroovy on the Shell
Groovy on the Shellsascha_klein
 
Goroutines and Channels in practice
Goroutines and Channels in practiceGoroutines and Channels in practice
Goroutines and Channels in practiceGuilherme Garnier
 

What's hot (20)

Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 Verona
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machine
 
Rust言語紹介
Rust言語紹介Rust言語紹介
Rust言語紹介
 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of Pedestal
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVM
 
typemap in Perl/XS
typemap in Perl/XS  typemap in Perl/XS
typemap in Perl/XS
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015
 
Function Call Optimization
Function Call OptimizationFunction Call Optimization
Function Call Optimization
 
Perl 6 by example
Perl 6 by examplePerl 6 by example
Perl 6 by example
 
Yapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed PerlYapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed Perl
 
Codes
CodesCodes
Codes
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)
 
Oral presentation v2
Oral presentation v2Oral presentation v2
Oral presentation v2
 
ssh.isdn.test
ssh.isdn.testssh.isdn.test
ssh.isdn.test
 
Groovy on the Shell
Groovy on the ShellGroovy on the Shell
Groovy on the Shell
 
Goroutines and Channels in practice
Goroutines and Channels in practiceGoroutines and Channels in practice
Goroutines and Channels in practice
 

Viewers also liked

Pwrake: Distributed Workflow Engine for e-Science - RubyConfX
Pwrake: Distributed Workflow Engine for e-Science - RubyConfXPwrake: Distributed Workflow Engine for e-Science - RubyConfX
Pwrake: Distributed Workflow Engine for e-Science - RubyConfXMasahiro Tanaka
 
多次元配列機能比較
多次元配列機能比較多次元配列機能比較
多次元配列機能比較Masahiro Tanaka
 
NArray and scientific computing with Ruby - RubyKaigi2010
NArray and scientific computing with Ruby - RubyKaigi2010NArray and scientific computing with Ruby - RubyKaigi2010
NArray and scientific computing with Ruby - RubyKaigi2010Masahiro Tanaka
 
Rubyのバージョン(鳥取ruby会)
Rubyのバージョン(鳥取ruby会)Rubyのバージョン(鳥取ruby会)
Rubyのバージョン(鳥取ruby会)Kei Matsunaga
 
Ruby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrakeRuby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrakeMasahiro Tanaka
 
Rubyによるデータ解析
Rubyによるデータ解析Rubyによるデータ解析
Rubyによるデータ解析Shugo Maeda
 
Rubyと機械学習の現状
Rubyと機械学習の現状Rubyと機械学習の現状
Rubyと機械学習の現状Aki Ariga
 
Pythonによる機械学習の最前線
Pythonによる機械学習の最前線Pythonによる機械学習の最前線
Pythonによる機械学習の最前線Kimikazu Kato
 

Viewers also liked (8)

Pwrake: Distributed Workflow Engine for e-Science - RubyConfX
Pwrake: Distributed Workflow Engine for e-Science - RubyConfXPwrake: Distributed Workflow Engine for e-Science - RubyConfX
Pwrake: Distributed Workflow Engine for e-Science - RubyConfX
 
多次元配列機能比較
多次元配列機能比較多次元配列機能比較
多次元配列機能比較
 
NArray and scientific computing with Ruby - RubyKaigi2010
NArray and scientific computing with Ruby - RubyKaigi2010NArray and scientific computing with Ruby - RubyKaigi2010
NArray and scientific computing with Ruby - RubyKaigi2010
 
Rubyのバージョン(鳥取ruby会)
Rubyのバージョン(鳥取ruby会)Rubyのバージョン(鳥取ruby会)
Rubyのバージョン(鳥取ruby会)
 
Ruby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrakeRuby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrake
 
Rubyによるデータ解析
Rubyによるデータ解析Rubyによるデータ解析
Rubyによるデータ解析
 
Rubyと機械学習の現状
Rubyと機械学習の現状Rubyと機械学習の現状
Rubyと機械学習の現状
 
Pythonによる機械学習の最前線
Pythonによる機械学習の最前線Pythonによる機械学習の最前線
Pythonによる機械学習の最前線
 

Similar to Tork03 LT

Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)ujihisa
 
Hacking Parse.y with ujihisa
Hacking Parse.y with ujihisaHacking Parse.y with ujihisa
Hacking Parse.y with ujihisaujihisa
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a bossgsterndale
 
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
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record.toster
 
Achieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangAchieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangSean Cribbs
 
Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011Tudor Girba
 
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate CompilersFunctional Thursday
 
CL metaprogramming
CL metaprogrammingCL metaprogramming
CL metaprogrammingdudarev
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby CoreHiroshi SHIBATA
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallySean Cribbs
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Aslak Hellesøy
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Aslak Hellesøy
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Aslak Hellesøy
 
Hacking parse.y (RubyConf 2009)
Hacking parse.y (RubyConf 2009)Hacking parse.y (RubyConf 2009)
Hacking parse.y (RubyConf 2009)ujihisa
 
あたかも自然言語を書くようにコーディングしてみる
あたかも自然言語を書くようにコーディングしてみるあたかも自然言語を書くようにコーディングしてみる
あたかも自然言語を書くようにコーディングしてみるKazuya Numata
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick touraztack
 

Similar to Tork03 LT (20)

Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)
 
Ruby 1.9
Ruby 1.9Ruby 1.9
Ruby 1.9
 
Hacking Parse.y with ujihisa
Hacking Parse.y with ujihisaHacking Parse.y with ujihisa
Hacking Parse.y with ujihisa
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
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]
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record
 
Achieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangAchieving Parsing Sanity In Erlang
Achieving Parsing Sanity In Erlang
 
Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011
 
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
 
Perl one liners
Perl one linersPerl one liners
Perl one liners
 
CL metaprogramming
CL metaprogrammingCL metaprogramming
CL metaprogramming
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby Core
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing Functionally
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009
 
Hacking parse.y (RubyConf 2009)
Hacking parse.y (RubyConf 2009)Hacking parse.y (RubyConf 2009)
Hacking parse.y (RubyConf 2009)
 
あたかも自然言語を書くようにコーディングしてみる
あたかも自然言語を書くようにコーディングしてみるあたかも自然言語を書くようにコーディングしてみる
あたかも自然言語を書くようにコーディングしてみる
 
Buffer OverFlow
Buffer OverFlowBuffer OverFlow
Buffer OverFlow
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 

Recently uploaded

08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 

Recently uploaded (20)

08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 

Tork03 LT

  • 1. Ruby Masaya TARUI
  • 3.
  • 4. Regexp • Rex • PEG ( Treetop , Citrus , Parslet ) • Ripper • Bootstrap • M17N • ERB • Racc
  • 6. • Racc strscan Ruby C → Rex
  • 7. Rex • C • Regexp! • Ruby /(match1)|(match2)|.../ Marshal capture [ match1,match1’s capture1, match1’s capture2... • Cature Capture 1.9 Lost Ruby parsec
  • 8. tork05 ( tork03 ) • @kawabata PEG : Parsing Expression Grammar https://github.com/kawabata/aozora-proc • • Ruby M17N Treetop, Citrus →(Rule Class ) • M17N
  • 9. PEG • • Packrat Parser O(n) Packrat Parser = •
  • 10. # -*- coding: utf-8 -*- require 'pp' require './peg.rb' expr_peg = <<'EOT' parser expr(top) top ← Expr !. ->$1 Expr ← Sum Sum ← Product (('+' / '-') Product)* -> { restruct(r) } Product ← Value (('*' / '/') Value)* -> { restruct(r) } Value ← Sp n:[0-9]+ Sp -> {n.join.to_i} / Sp '(' e:Expr ')' Sp -> e Sp ← ( " " / "t" / "n" )* EOT def restruct(r) r[1].inject(r[0]){|a,b| [b[0],a,b[1]] } end expr_parser = PEG::ParserGenerator.parse(expr_peg) require 'pp' expr = " 1+ 2 * (3 - 4) / 5 + 6 " pp expr pp expr_parser.parse(expr) => " 1+ 2 * (3 - 4) / 5 + 6 " ["+", ["+", 1, ["/", ["*", 2, ["-", 3, 4]], 5]], 6] StackOverFlow orz
  • 11. PEG • PEG • M17N OK
  • 12. -> { restruct(r) } • Ruby → Ruby
  • 13. parse.y $ wc parse.y 10745 27247 234392 parse.y •
  • 14. Ruby Scanner parse “a <%= ‘%%>’ %>b”
  • 15. -> { restruct(r) } • Ruby → Ruby • 8 10
  • 16. ERB Ruby Scanner class TrimScanner < Scanner # :nodoc: def initialize(src, trim_mode, percent) super @trim_mode = trim_mode @percent = percent if @trim_mode == '>' @scan_line = self.method(:trim_line1) elsif @trim_mode == '<>' @scan_line = self.method(:trim_line2) elsif @trim_mode == '-' @scan_line = self.method(:explicit_trim_line) else @scan_line = self.method(:scan_line) end end attr_accessor :stag def scan(&block) @stag = nil if @percent @src.each_line do |line| percent_line(line, &block) end else @scan_line.call(@src, &block) end nil end def percent_line(line, &block) if @stag || line[0] != ?% return @scan_line.call(line, &block) end line[0] = '' if line[0] == ?% @scan_line.call(line, &block) else yield(PercentLine.new(line.chomp)) end end
  • 17. def trim_line2(line) head = nil line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>n|%>|n|z)/m) do |tokens| tokens.each do |token| next if token.empty? head = token unless head ERB Ruby Scanner if token == "%>n" yield('%>') if is_erb_stag?(head) yield(:cr) else yield("n") end head = nil else yield(token) head = nil if token == "n" end end end end def explicit_trim_line(line) line.scan(/(.*?)(^[ t]*<%-|<%-|<%%|%%>|<%=|<%#|<%|-%>n|-%>|%>|z)/m) do |tokens| tokens.each do |token| next if token.empty? if @stag.nil? && /[ t]*<%-/ =~ token yield('<%') elsif @stag && token == "-%>n" yield('%>') yield(:cr) elsif @stag && token == '-%>' yield('%>') else yield(token) end end end end ERB_STAG = %w(<%= <%# <%) def is_erb_stag?(s) ERB_STAG.member?(s) end end Scanner.default_scanner = TrimScanner Scanner
  • 18. Racc Ruby Scanner def scan_action buf = '' nest = 1 pre = nil @in_block = 'action' begin pre = nil if s = reads(/As+/) # does not set 'pre' buf << s end until @line.empty? if s = reads(/A[^'"`{}%#/$]+/) buf << (pre = s) next end case ch = read(1) when '{' nest += 1 buf << (pre = ch) when '}' nest -= 1 if nest == 0 @in_block = nil return buf end buf << (pre = ch) when '#' # comment buf << ch << @line break when "'", '"', '`' buf << (pre = scan_quoted(ch)) when '%' if literal_head? pre, @line # % string, regexp, array buf << ch case ch = read(1) when /[qQx]/n buf << ch << (pre = scan_quoted(read(1), '%string')) when /wW/n
  • 19. # % string, regexp, array buf << ch case ch = read(1) when /[qQx]/n buf << ch << (pre = scan_quoted(read(1), '%string')) Racc Ruby Scanner when /wW/n buf << ch << (pre = scan_quoted(read(1), '%array')) when /s/n buf << ch << (pre = scan_quoted(read(1), '%symbol')) when /r/n buf << ch << (pre = scan_quoted(read(1), '%regexp')) when /[a-zA-Z0-9= ]/n # does not include "_" scan_error! "unknown type of % literal '%#{ch}'" else buf << (pre = scan_quoted(ch, '%string')) end else # operator buf << '||op->' if $raccs_print_type buf << (pre = ch) end when '/' if literal_head? pre, @line # regexp buf << (pre = scan_quoted(ch, 'regexp')) else # operator buf << '||op->' if $raccs_print_type buf << (pre = ch) end when '$' # gvar buf << ch << (pre = read(1)) else raise 'racc: fatal: must not happen' end end buf << "n" end while next_line() raise 'racc: fatal: scan finished before parser finished' end
  • 20.
  • 21. Ripper! • parse.y 1.9 Ruby • irb(main):001:0> Ripper.parse("a = b + 1") => nil
  • 22. Ripper • test/ripper/test_files.rb class Parser < Ripper PARSER_EVENTS.each {|n| eval "def on_#{n}(*args) r = [:#{n}, *args]; r.inspect; Object.new end" } SCANNER_EVENTS.each {|n| eval "def on_#{n}(*args) r = [:#{n}, *args]; r.inspect; Object.new end" } end •
  • 23. Ripper Scanner class RubyCodeDetector < Ripper class ParseError < Exception attr_reader :message,:result def initialize(r,msg) @result = r @message = msg end end def on_parse_error(msg) l = @lines[lineno-1][0,column-1] src = (@lines[0,lineno-1]+[l])*"n" src.force_encoding(@src.encoding) raise ParseError.new(src,msg) end def initialize(*args) @src=args[0] @lines=@src.split(/n/).map{|i| i.force_encoding("ASCII-8BIT") } super end def parse super raise ParseError.new(@src,"syntax error, unexpected $end, expecting '}'") nil rescue ParseError => e if e.message =~ /G syntax error, unexpected '}'/ e.result else raise $! nil end end end
  • 24. Ripper Scanner class RubyCodeDetector < Ripper class ParseError < Exception attr_reader :message,:result def initialize(r,msg) @result = r @message = msg end end def on_parse_error(msg) l = @lines[lineno-1][0,column-1] src = (@lines[0,lineno-1]+[l])*"n" src.force_encoding(@src.encoding) raise ParseError.new(src,msg) end def initialize(*args) @src=args[0] @lines=@src.split(/n/).map{|i| i.force_encoding("ASCII-8BIT") } super end def parse super raise ParseError.new(@src,"syntax error, unexpected $end, expecting '}'") nil rescue ParseError => e if e.message =~ /G syntax error, unexpected '}'/ e.result else raise $! nil end end end
  • 25. Regexp • Rex • PEG ( Treetop , Citrus , Parslet ) • Ripper • Bootstrap • M17N • ERB • Racc
  • 26. • Ripper 1.9 • Ripper

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n