Slide 1

Slide 1 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Does Ruby Parser dream of highly expressive grammar? Yudai TAKADA @ydah 2024/05/16 RubyKaigi 2024

Slide 2

Slide 2 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Yudai TAKADA ΫϦΤΠςΟϒεϖʔε ͜ͷൣғͷதͰσβΠϯ͍ͯͩ͘͠͞ About me Confidential @ydah Software Engineer at ANDPAD Member of Re-architecting team https://ydah.net

Slide 3

Slide 3 text

© 2024 ANDPAD All Rights Reserved. Confidential Service Summary Office Construction-site Sales / Site Supervisor / Architect Office worker / Managerial position (Ruby logo Copyright © 2006, Yukihiro Matsumoto) Cloud-based Project Management Software Products powered by Ruby Carpenter / Vendor Manufacturer / Distribution

Slide 4

Slide 4 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ ΫϦΤΠςΟϒεϖʔε ͜ͷൣғͷதͰσβΠϯ͍ͯͩ͘͠͞ We are Platinum (Party) Sponsor! Confidential

Slide 5

Slide 5 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Yudai TAKADA ΫϦΤΠςΟϒεϖʔε ͜ͷൣғͷதͰσβΠϯ͍ͯͩ͘͠͞ About me Confidential @ydah RuboCop RSpec team Co-Founder of Kyobashi.rb Member of RubyKansai & Asakura.rb Maintainer of Committee Member of Dragon book study club

Slide 6

Slide 6 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ About me Confidential

Slide 7

Slide 7 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ About me Confidential

Slide 8

Slide 8 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Yudai TAKADA ΫϦΤΠςΟϒεϖʔε ͜ͷൣғͷதͰσβΠϯ͍ͯͩ͘͠͞ About me Confidential @ydah RuboCop RSpec team Committer of Lrama (new!) Co-Founder of Kyobashi.rb Member of RubyKansai & Asakura.rb Maintainer of Committee Member of Dragon book study club

Slide 9

Slide 9 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ “これが俺の選んだ仕事なんだ。一生を賭けてやっ てる仕事なんだよ。” —東 光太郎 Confidential Introduction

Slide 10

Slide 10 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • https://github.com/ruby/lrama • LALR (1) parser generator written by Ruby • Output a LALR parser written by C with “parse.y” as input • Replace GNU Bison with Lrama in Ruby 3.3.0 • https://bugs.ruby-lang.org/issues/19637 What’s the Lrama? Confidential

Slide 11

Slide 11 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • We needed to support multiple versions of Bison • Must be able to build with a different version of Bison • New features are added, but they are not available • Difficult to expand Bison functionality • Ruby is not the only user of Bison • Other common parser generators have similar problems Why use Lrama instead of Bison? Confidential

Slide 12

Slide 12 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Maintainability • “parse.y” is difficult • be likened to a Demon Castle, Hell, “魔境” • What's the difficulty? • Grammar provided by Bison is primitive • Parser and Lexer are tightly coupled • Difficult to resolve S/R or R/R conflicts • Need to improve development experience What’s the issue? Confidential

Slide 13

Slide 13 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Today’s Talk

Slide 14

Slide 14 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Today’s Talk Confidential • Improve the developer experience of parse.y • Fight 3 challenges to grammar Maintainability • Consider the possibility of a grammatical extension approach Primitive Grammar Tightly coupled Lexer & Parser Difficult to resolve Conflicts

Slide 15

Slide 15 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential “銀河連邦の一員たるを示すウルトラリングを今お 前たちに与えた。そのリングの光る時、お前たち は私の与えた大いなる力を知るだろう” — ウルトラマンA Primitive Grammar

Slide 16

Slide 16 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ ʆ • Rules have same structure and same actions Primitive Grammar Confidential opt_args_tail : ',' args_tail { $$ = $2; ɹɹɹ / * % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; opt_block_args_tail : ',' block_args_tail { $$ = $2; ɹɹɹ / * % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ;

Slide 17

Slide 17 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Rules have same structure and same actions Confidential opt_args_tail : ',' args_tail { $$ = $2; ɹɹɹ / * % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; opt_block_args_tail : ',' block_args_tail { $$ = $2; ɹɹɹ / * % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; The only difference is this nonterminal symbol Primitive Grammar

Slide 18

Slide 18 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential • > Code should be clear and simple straightforward logic, natural expression, conventional language use, meaningful names, neat formatting, helpful comments-and it should avoid clever tricks and unusual constructions. • Brian W. Kernighan, Rob Pike. 1999/02/04 The Practice of Programming. Addison-Wesley Primitive Grammar

Slide 19

Slide 19 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Parameterizing Rules

Slide 20

Slide 20 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • The definition of a non-terminal symbol can be parameterized with other (terminal or non-terminal) symbols • Idea of Parameterizing Rules comes from Menhir LR(1) parser generator • https://gallium.inria.fr/~fpottier/menhir/ manual.html#sec32 Parameterizing Rules Confidential

Slide 21

Slide 21 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • How to define a Rule Confidential %rule option(X) : / * empty * / | X ; %rule preceded(opening, X) : opening X { $$ = $2; } ; Start with the directive %rule Parameterizing Rules

Slide 22

Slide 22 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • How to define a Rule Confidential %rule option(X) : / * empty * / | X ; %rule preceded(opening, X) : opening X { $$ = $2; } ; Define the rule name and parameters pass to the rule Parameterizing Rules

Slide 23

Slide 23 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • How to define a Rule Confidential %rule option(X) : / * empty * / | X ; %rule preceded(opening, X) : opening X { $$ = $2; } ; Define the RHS Parameterizing Rules

Slide 24

Slide 24 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • How to use a Rule Confidential %rule option(X) : / * empty * / | X ; % % opt_foo: option(foo) ; Parameterizing Rules

Slide 25

Slide 25 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • How to use a Rule Confidential %rule option(X) : / * empty * / | X ; % % opt_foo: option(foo) ; Parameterizing Rules foo

Slide 26

Slide 26 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Registers a rule in resolver based on the definition of the rule Confidential %rule option(X) : / * empty * / { $$ = 0} | X ; Rule name Parameter name Parameter counts RHS User code Parameterizing Rules

Slide 27

Slide 27 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Find parameterizing rule by rule name and param count Confidential opt_foo: option(number) ; • name: list, param_count: 1 • name: no_empty_list, param_count: 1 • name: pair, param_count: 2 • name: option, param_count: 1 • name: preceded, param_count: 2 Parameterizing rules Parameterizing Rules •Rule name: option •Parameter counts: 1

Slide 28

Slide 28 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • If the same name and parameter count rules Confidential opt_foo: option(number) ; • name: list, param_count: 1 • name: no_empty_list, param_count: 1 • name: pair, param_count: 2 • name: option, param_count: 1 • name: preceded, param_count: 2 • name: option, param_count: 1 parameterizing_rules Parameterizing Rules •Rule name: option •Parameter counts: 1

Slide 29

Slide 29 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Example of Rule expand Confidential Parameterizing Rules %rule option(X) : / * empty * / | X ; % % opt_foo: option(number) ; if foo else # <— this end

Slide 30

Slide 30 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Example of Rule expand Confidential opt_foo option_number %empty number RHS RHS Rule name Concated arguments names opt_foo: option(number) ; %rule option(X) : / * empty * / | X ; Parameterizing Rules

Slide 31

Slide 31 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Example of Rule expand Confidential opt_foo option_number %empty number RHS RHS opt_foo: option(number) ; %rule option(X) : / * empty * / | X ; Parameterizing Rules

Slide 32

Slide 32 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential opt_args_tail : ',' args_tail { $$ = $2; ɹɹɹ / * % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; opt_block_args_tail : ',' block_args_tail { $$ = $2; ɹɹɹ / * % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; • Using Parameterizing rules ... Parameterizing Rules

Slide 33

Slide 33 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential %rules args_tail(tail) : ',' tail { $$ = $2; ɹɹɹ / * % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; % % opt_args_tail: args_tail(args_tail) ; opt_block_args_tail : args_tail(block_args_tail) ; • Can be abstracted in this way!! Parameterizing Rules

Slide 34

Slide 34 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential %rule foo(X) : X { $$ = $1; } ; % % program : foo(number) { $$ = $1; } ; • But we can't access the symbol as it is. Because must specify type information for all symbols referenced in the action. Parameterizing Rules with Tag

Slide 35

Slide 35 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential %union { int num; char * str; } %token tNUMBER %token tSTRING %type number • Provide type information for terminal/nonterminal symbols Parameterizing Rules with Tag

Slide 36

Slide 36 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential %union { int num; char * str; } %token tNUMBER %token tSTRING %type number • Provide type information for terminal/nonterminal symbols Parameterizing Rules with Tag Tag

Slide 37

Slide 37 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • But hard to specify with `%token` or `%type` Confidential %rule foo(X) : X { $$ = $1; } ; % % program : foo(number, string) { $$ = $1; } ; Parameterizing Rules with Tag

Slide 38

Slide 38 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • But hard to specify with `%token` or `%type` Confidential %rule foo(X) : X { $$ = $1; } ; % % program : foo(number, string) { $$ = $1; } ; program foo_number_string Parameterizing Rules with Tag

Slide 39

Slide 39 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Example of how to specify a Tag: Confidential %rule foo(X) : X { $$ = $1; } ; % % program : foo(number) { $$ = $1; } ; Specify a Tag after the parameterizing rules call. Parameterizing Rules with Tag

Slide 40

Slide 40 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Other examples: Confidential %union { int num; char * str; } %token number %token string %rule foo(X) : X { $$ = $1; } ; % % program : foo(number) { $$ = $1; } : foo(string) { $$ = $1; } ; Parameterizing Rules with Tag

Slide 41

Slide 41 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Other examples: Confidential %union { int num; char * str; } %token number %token string %rule foo(X) : X { $$ = $1; } ; % % program : foo(number) { $$ = $1; } : foo(string) { $$ = $1; } ; int char* int or char* Parameterizing Rules with Tag

Slide 42

Slide 42 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Reduce redundant specifications on callers Confidential Parameterizing Rules with Tag %rule foo(X) : X { $$ = $1; } | foo(X) { $$ = $1 + $2; } ; % % program : foo(number) { $$ = $1; } ; other : bar foo(number) baz { $$ = $1 + $2 + $3; } ;

Slide 43

Slide 43 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Reduce redundant specifications on callers Confidential %rule foo(X) : X { $$ = $1; } | foo(X) { $$ = $1 + $2; } ; % % program : foo(number) { $$ = $1; } ; other : bar foo(number) baz { $$ = $1 + $2 + $3; } ; Parameterizing Rules with Tag

Slide 44

Slide 44 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Tag can be specified on the callee side! Confidential %rule foo(X) : X { $$ = $1; } | foo(X) X { $$ = $1 + $2; } ; % % program : foo(number) { $$ = $1; } ; other : bar foo(number) baz { $$ = $1 + $2 + $3; } ; Parameterizing Rules with Tag

Slide 45

Slide 45 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • About Tag Priority Confidential %rule foo(X) : X { $$ = $1; } ; % % program : foo(number) { $$ = $1; } ; When specified on the callee and caller sides like this, the tag on the caller side is specified. Parameterizing Rules with Tag

Slide 46

Slide 46 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • About Tag Priority Confidential %rule foo(X) : X { $$ = $1; } ; % % program : foo(number) { $$ = $1; } ; In this example, `` is specified as the reference type pointed to by `$$`on the callee side and `$1` on the caller side. Parameterizing Rules with Tag

Slide 47

Slide 47 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • > To help programmers be productive, I focus on making programs succinct in Ruby. I try to make programs compact. I also focus on providing very rich features in class libraries. If you have a library method to do the things that you want to do, you don't need to write much code. • “Dynamic Productivity with Ruby - A Conversation with Yukihiro Matsumoto, Part II” 2003/11/17 • https://www.artima.com/articles/dynamic-productivity-with-ruby Productivity, Efficiency, and Robustness Confidential

Slide 48

Slide 48 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • The following comma-separated list structure is a common structure Confidential list : item | list ',' item ; def foo(bar, baz) # do something end [foo, bar, baz].each do |item| # do something end foo(bar, baz) Productivity, Efficiency, and Robustness

Slide 49

Slide 49 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Standard Library

Slide 50

Slide 50 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Provides a Standard Library of rules with a general structure, such as `option` or `list` • By default, it is joined with all grammar specifications • It is stored in a file name lib/lrama/grammar/stdlib.y, which is embedded inside grammar file when before parsing • If you don’t want to embed the Standard Library, you should add the `%no-stdlib` directive to the grammar file. Standard Library Confidential

Slide 51

Slide 51 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • The following three rules can be created using the familiar regular expression-like syntax Confidential Name Recognizes Alias option(X) є | X X? list(X) a possibly empty sequence of X’s X* nonempty_list(X) a nonempty sequence of X’s X+ Standard Library

Slide 52

Slide 52 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • In the actual case of the replacement, the following replaced the non-terminal symbol for an optional line break Confidential opt_nl : / * none * / | '\n' ; rparen : opt_nl ')' Standard Library

Slide 53

Slide 53 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • In the actual case of the replacement, the following replaced the non-terminal symbol for an optional line break Confidential opt_nl : / * none * / | '\n' ; rparen : opt_nl ')' rparen : '\n'? ')' Standard Library

Slide 54

Slide 54 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Grammar provided by Bison is primitive • We got a power to take out the structure in parse.y! • Parameterizing rules can name patterns to clarify the intent of the rule and allow patterns to be reused • Standard Library provides a simple way to write rules for common structures Summary Confidential

Slide 55

Slide 55 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ “お待ちなさいタロウ。このブレスレットはあなた の新しい武器です” — ウルトラの母 Confidential Tightly coupled Lexer & Parser

Slide 56

Slide 56 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • “Ruby Parser։ൃ೔ࢽ (6) - parse.yͷMaintainabilityͷ࿩” ͔Ͷ͜ʹ͖ͬ 2023/04/04. • https://yui-knk.hatenablog.com/entry/2023/04/04/190413 • > parserͱlexer͕ͳͥີ݁߹͍ͯ͠Δͷ͔ • > 2. ಛఆͷੜ੒نଇΛ͋Δ৚݅ԼͰ͸ແޮʹ͢ΔͨΊ • > Why parser and lexer are tightly coupled? • > 2. To invalidate certain generation rules under certain conditions Tightly coupled Lexer & Parser Confidential

Slide 57

Slide 57 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential • lambda's temporary arguments must not have ` ... ` cannot be specified irb(main) : 001> - > (a) {} = > # irb(main) : 002> - > (a=1) {} = > # irb(main) : 003> - > ( . . . ) {} : 187:in `loop': (irb) : 3 : syntax error, unexpected . . . , expecting ')' (SyntaxError) - > ( . . . ) {} ^ ~ ~ Tightly coupled Lexer & Parser

Slide 58

Slide 58 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential • There's a hack that looks at the lex_state and returns a token that will cause a syntax error if it's a lambda temporary argument case '.': { int is_beg = IS_BEG(); SET_LEX_STATE(EXPR_BEG); if ((c = nextc(p)) = = '.') { if ((c = nextc(p)) = = '.') { if (p - > ctxt.in_argdef) { SET_LEX_STATE(EXPR_ENDARG); return tBDOT3; } if (p - > lex.paren_nest = = 0 & & looking_at_eol_p(p)) { rb_warn0(" . . . at EOL, should be parenthesized?"); } else if (p - > lex.lpar_beg > = 0 & & p - > lex.lpar_beg+1 = = p - > lex.paren_nest) { if (IS_lex_state_for(last_state, EXPR_LABEL)) return tDOT3; } Tightly coupled Lexer & Parser

Slide 59

Slide 59 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential • There's a hack that looks at the lex_state and returns a token that will cause a syntax error if it's a lambda temporary argument case '.': { int is_beg = IS_BEG(); SET_LEX_STATE(EXPR_BEG); if ((c = nextc(p)) = = '.') { if ((c = nextc(p)) = = '.') { if (p - > ctxt.in_argdef) { SET_LEX_STATE(EXPR_ENDARG); return tBDOT3; } if (p - > lex.paren_nest = = 0 & & looking_at_eol_p(p)) { rb_warn0(" . . . at EOL, should be parenthesized?"); } else if (p - > lex.lpar_beg > = 0 & & p - > lex.lpar_beg+1 = = p - > lex.paren_nest) { if (IS_lex_state_for(last_state, EXPR_LABEL)) return tDOT3; } Tightly coupled Lexer & Parser

Slide 60

Slide 60 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Very abbreviated diagram of the RHS: Tightly coupled Lexer & Parser RHS args_forward tBDOT3 args_tail RHS RHS f_larglist f_arglist f_args RHS RHS Confidential

Slide 61

Slide 61 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • (Maybe) simplest solution Tightly coupled Lexer & Parser RHS RHS RHS f_arglist RHS args_tail f_args args_forward tBDOT3 RHS f_larglist RHS largs_tail f_largs Confidential

Slide 62

Slide 62 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • (Maybe) simplest solution Tightly coupled Lexer & Parser RHS RHS RHS f_arglist RHS args_tail f_args args_forward tBDOT3 RHS f_larglist RHS largs_tail f_largs It's not good to have to make the same changes in all… Confidential

Slide 63

Slide 63 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Parameterizing Rules with Conditional Statements

Slide 64

Slide 64 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Conceptual diagram: Parameterizing Rules with Conditional Statements f_arglist args_tail args_forward tBDOT3 f_larglist args_tail f_args lambda? No f_args Confidential

Slide 65

Slide 65 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Parameterizing Rules with Conditional Statements • args_forward is included in RHS unless lambda f_arglist args_tail f_args args_forward tBDOT3 f_larglist args_tail f_args lambda? No Confidential

Slide 66

Slide 66 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • args_forward should not be included in RHS if lambda Parameterizing Rules with Conditional Statements f_arglist args_tail f_args args_forward tBDOT3 f_larglist args_tail f_args lambda? No Confidential

Slide 67

Slide 67 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential • [PoC] Intoroduce parameterizing rules with conditional statement #418 • https://github.com/ruby/lrama/pull/418 Parameterizing Rules with Conditional Statements

Slide 68

Slide 68 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential • How to use a conditional (1) %rule def i ned_rule(X, condition) : X { $$ = $1; } %if(condition) ; % % r_true : def i ned_rule(number, %true) ; r_false : def i ned_rule(number, %false) ; This syntax is like the Ruby postfix if. If condition is false, the row creation rules are not expanded. Parameterizing Rules with Conditional Statements

Slide 69

Slide 69 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential • Result (1) ❯ exe/lrama - - trace=rules sample/calc.y Grammar rules: $accept - > r_true YYEOF def i ned_rule_number_true - > number r_true - > def i ned_rule_number_true r_false - > ε Parameterizing Rules with Conditional Statements

Slide 70

Slide 70 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential • How to use a conditional (2) %rule def i ned_rule(X, condition) : %if(condition) X %endif X { $$ = $1; } ; % % r_true : def i ned_rule(number, %true) ; r_false : def i ned_rule(number, %false) ; If statementIf condition is false, it is equivalent to missing RHS between `%if` and `%endif` Parameterizing Rules with Conditional Statements

Slide 71

Slide 71 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential • Result (2) ❯ exe/lrama - - trace=rules sample.y Grammar rules: $accept - > r_true YYEOF def i ned_rule_number_true - > number number r_true - > def i ned_rule_number_true def i ned_rule_number_false - > number r_false - > def i ned_rule_number_false Parameterizing Rules with Conditional Statements

Slide 72

Slide 72 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Parser and Lexer are tightly coupled • Parameterizing rules still have room to evolve! • Suggested that evolution makes them more flexible • What to parameterize? Maybe we can solve more other problems if we consider Summary Confidential

Slide 73

Slide 73 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential “太陽、この私をもっと強くしてくれ。お前がお前 の子である地球を愛しているなら、この私にベム スターと互角に戦える力を与えてくれ!” — 郷秀樹 Difficult to resolve Conflicts

Slide 74

Slide 74 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • It is known that the following arithmetic grammar does not work as expected Difficult to resolve Conflicts Confidential expr : number { $$ = $1; } | expr op expr { if ($2 = = '+') $$ = $1 + $3; else $$ = $1 * $3; } ; op : PLUS { $$ = '+'; } | TIMES { $$ = ‘*'; } ;

Slide 75

Slide 75 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ shift/reduce conflict on token PLUS : op: • PLUS (rule 3) expr: expr op expr • (rule 2) : (snip) shift/reduce conflict on token TIMES : op: • TIMES (rule 4) expr: expr op expr • (rule 2) • There is a S/R conflict despite the declaration of priority Confidential Difficult to resolve Conflicts

Slide 76

Slide 76 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • So how do you resolve conflicts from here? Confidential expr : number { $$ = $1; } | expr op expr { if ($2 = = '+') $$ = $1 + $3; if ($2 = = ‘*') $$ = $1 * $3; } ; op : PLUS { $$ = '+'; } | TIMES { $$ = ‘*'; } ; Difficult to resolve Conflicts

Slide 77

Slide 77 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ expr : number { $$ = $1; } | expr PLUS expr { $$ = $1 + $3; } | expr TIMES expr { $$ = $1 * $3; } ; • Standard workaround: Confidential Part of the structure of the original generation rule is destroyed Difficult to resolve Conflicts

Slide 78

Slide 78 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Inlining

Slide 79

Slide 79 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Provides a solution to avoid conflicts without changing grammar • Idea of Inlining comes from Menhir LR(1) parser generator • https://gallium.inria.fr/~fpottier/menhir/ manual.html#sec37 Inlining Confidential

Slide 80

Slide 80 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ %rule %inline op: PLUS { + } | TIMES { * } ; % % expr : number { $$ = $1; } | expr op expr { $$ = $1 $2 $3; } ; • How to use a Inline Rule Confidential Inlining

Slide 81

Slide 81 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ %rule %inline op: PLUS { + } | TIMES { * } ; % % expr : number { $$ = $1; } | expr op expr { $$ = $1 $2 $3; } ; • How to use a Inline Rule Confidential Inlining

Slide 82

Slide 82 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ %rule %inline op: PLUS { + } | TIMES { * } ; % % expr : number { $$ = $1; } | expr op expr { $$ = $1 $2 $3; } ; • How to use a Inline Rule Confidential Inlining

Slide 83

Slide 83 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ %rule %inline op: PLUS { + } | TIMES { * } ; % % expr : number { $$ = $1; } | expr op expr { $$ = $1 $2 $3; } ; • How to use a Inline Rule Confidential Inlining

Slide 84

Slide 84 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ %rule %inline op: PLUS { + } | TIMES { * } ; % % expr : number { $$ = $1; } | expr op expr { $$ = $1 $2 $3; } ; • How to use a Inline Rule Confidential Inlining

Slide 85

Slide 85 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ ❯ exe/lrama - - trace=actions sample.y Grammar rules with actions: $accept - > expr YYEOF {} expr - > number { $$ = $1; } expr - > expr PLUS expr { $$ = $1 + $3; } expr - > expr TIMES expr { $$ = $1 * $3; } • Rules and Actions After Inlining: Confidential Inlining

Slide 86

Slide 86 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • However, the current situation is still a naive implementation • Like macros, code is rewritten when rules are deployed • A new grammar is required • Keep the code in the defining action of Inlining • Reference on the side using Inlining • We need to think about intermediate language design • Finally, we aims to output a parser written in various languages • We need a transpiler to convert to each language • We need to design an intermediate language that looks to the future Confidential Inlining

Slide 87

Slide 87 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Difficult to resolve S/R or R/R conflicts • The ability to resolve conflicts without losing information about the structure of Inlining is a powerful force • Inlining is still a naive implementation and still needs to be improved • We need a forward-looking intermediate language design Summary Confidential

Slide 88

Slide 88 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ “これからも、恐ろしい敵は次々と現れるだろう。 だが、我々がウルトラ警備隊魂を持ち続ける限 り、地球の平和は守られるに違いない" —モロボシ・ダン Confidential Conclusion

Slide 89

Slide 89 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • It was suggested that 3 threats to maintainability could be well fought by extending grammar • There's still room for expansion, so developing richer grammar can enhance maintainability • We can now use more convenient parser generator features! (if we implemented it 😉 ) Conclusion Confidential

Slide 90

Slide 90 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • @yui-knk • @junk0612 • @amatsuda • @jinroq Acknowledgements Confidential

Slide 91

Slide 91 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Lrama LALR (1) parser generator https://github.com/ruby/lrama • Menhir Reference Manual(version 20231231) https://gallium.inria.fr/~fpottier/menhir/manual.html • Yuichiro Kaneko “Ruby Parser開発日誌 (5) - Lrama LALR (1) parser generatorを実装した” かねこにっき 2023/03/13. https://yui-knk.hatenablog.com/entry/2023/03/13/101951 • Yuichiro Kaneko “Ruby Parser開発日誌 (6) - parse.yのMaintainabilityの話” かねこにっき 2023/04/04. https://yui-knk.hatenablog.com/entry/2023/04/04/190413 • Yuichiro Kaneko “Lrama LRパーサジェネレータが切り開く、Rubyの構文解析の未来” gihyo.jp Ruby3.3リリー ス! 新機能解説 2024/01/24. https://gihyo.jp/article/2024/01/ruby3.3-lrama • Bill Venners, Yukihiro Matsumoto “Dynamic Productivity with Ruby - A Conversation with Yukihiro Matsumoto, Part II” 2003/11/17” https://www.artima.com/articles/dynamic-productivity-with-ruby References Confidential

Slide 92

Slide 92 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ Confidential Thank you!!