From df8e892b4e7c1f044ab21fa85f5312e92c7b0269 Mon Sep 17 00:00:00 2001 From: ydah Date: Thu, 2 May 2024 17:39:24 +0900 Subject: [PATCH 1/3] Add support for aliased Named References for actions of rhs in Parameterizing rules --- lib/lrama/grammar/binding.rb | 11 ++++++++++- sig/lrama/grammar/binding.rbs | 4 ++++ .../user_defined/with_action_and_named_references.y | 2 +- spec/lrama/parser_spec.rb | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/lrama/grammar/binding.rb b/lib/lrama/grammar/binding.rb index e5ea3fb0..21b6ad5b 100644 --- a/lib/lrama/grammar/binding.rb +++ b/lib/lrama/grammar/binding.rb @@ -16,9 +16,18 @@ def resolve_symbol(symbol) resolved_args = symbol.args.map { |arg| resolve_symbol(arg) } Lrama::Lexer::Token::InstantiateRule.new(s_value: symbol.s_value, location: symbol.location, args: resolved_args, lhs_tag: symbol.lhs_tag) else - @parameter_to_arg[symbol.s_value] || symbol + parameter_to_arg(symbol) || symbol end end + + private + + def parameter_to_arg(symbol) + if (arg = @parameter_to_arg[symbol.s_value].dup) + arg.alias_name = symbol.alias_name + end + arg + end end end end diff --git a/sig/lrama/grammar/binding.rbs b/sig/lrama/grammar/binding.rbs index 817d7eb1..3d6b1a6c 100644 --- a/sig/lrama/grammar/binding.rbs +++ b/sig/lrama/grammar/binding.rbs @@ -10,6 +10,10 @@ module Lrama def initialize: (Grammar::ParameterizingRule::Rule parameterizing_rule, Array[Lexer::Token] actual_args) -> void def resolve_symbol: (Lexer::Token symbol) -> Lexer::Token + + private + + def parameter_to_arg: (Lexer::Token symbol) -> Lexer::Token? end end end diff --git a/spec/fixtures/parameterizing_rules/user_defined/with_action_and_named_references.y b/spec/fixtures/parameterizing_rules/user_defined/with_action_and_named_references.y index 85ae0d5c..9bb96b66 100644 --- a/spec/fixtures/parameterizing_rules/user_defined/with_action_and_named_references.y +++ b/spec/fixtures/parameterizing_rules/user_defined/with_action_and_named_references.y @@ -16,7 +16,7 @@ static int yyerror(YYLTYPE *loc, const char *str); %token number %token string -%rule pair(X, Y): X ',' Y { printf("(%d, %d)\n", $X, $3); } +%rule pair(X, Y): X ',' Y[alias] { printf("(%d, %d)\n", $X, $alias); } ; %% diff --git a/spec/lrama/parser_spec.rb b/spec/lrama/parser_spec.rb index 40512c87..c188c11c 100644 --- a/spec/lrama/parser_spec.rb +++ b/spec/lrama/parser_spec.rb @@ -1719,7 +1719,7 @@ grammar.find_symbol_by_s_value!("string") ], lhs_tag: nil, - token_code: T::UserCode.new(s_value: " printf(\"(%d, %d)\\n\", $X, $3); "), + token_code: T::UserCode.new(s_value: " printf(\"(%d, %d)\\n\", $X, $alias); "), nullable: false, precedence_sym: grammar.find_symbol_by_s_value!("string"), lineno: 24, From 6024b2b180beed7bca99fc62e789d16562699f0d Mon Sep 17 00:00:00 2001 From: ydah Date: Sat, 4 May 2024 19:30:38 +0900 Subject: [PATCH 2/3] Change the test case to be a good example --- .../with_action_and_named_references.y | 9 ++++--- spec/lrama/parser_spec.rb | 24 +++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/spec/fixtures/parameterizing_rules/user_defined/with_action_and_named_references.y b/spec/fixtures/parameterizing_rules/user_defined/with_action_and_named_references.y index 9bb96b66..e68da1fe 100644 --- a/spec/fixtures/parameterizing_rules/user_defined/with_action_and_named_references.y +++ b/spec/fixtures/parameterizing_rules/user_defined/with_action_and_named_references.y @@ -10,18 +10,17 @@ static int yyerror(YYLTYPE *loc, const char *str); %union { int i; - char *s; } %token number -%token string +%token summand -%rule pair(X, Y): X ',' Y[alias] { printf("(%d, %d)\n", $X, $alias); } - ; +%rule plus(X): X '+' number[addend] { $$ = $X + $addend; } + ; %% -program : pair(number, string) { printf("pair odd even\n"); } +program : plus(summand) { printf("plus number\n"); } ; %% diff --git a/spec/lrama/parser_spec.rb b/spec/lrama/parser_spec.rb index c188c11c..f03322cd 100644 --- a/spec/lrama/parser_spec.rb +++ b/spec/lrama/parser_spec.rb @@ -1693,7 +1693,7 @@ it "expands parameterizing rules" do expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 0, nullable: false), - Sym.new(id: T::Ident.new(s_value: "pair_number_string"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 1, nullable: false), + Sym.new(id: T::Ident.new(s_value: "plus_summand"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 1, nullable: false), Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 8, tag: nil, term: false, token_id: 2, nullable: false), ]) @@ -1708,33 +1708,33 @@ token_code: nil, nullable: false, precedence_sym: grammar.find_symbol_by_s_value!("YYEOF"), - lineno: 24, + lineno: 23, ), Rule.new( id: 1, - lhs: grammar.find_symbol_by_s_value!("pair_number_string"), + lhs: grammar.find_symbol_by_s_value!("plus_summand"), rhs: [ - grammar.find_symbol_by_s_value!("number"), - grammar.find_symbol_by_number!(5), - grammar.find_symbol_by_s_value!("string") + grammar.find_symbol_by_s_value!("summand"), + grammar.find_symbol_by_s_value!("'+'"), + grammar.find_symbol_by_s_value!("number") ], lhs_tag: nil, - token_code: T::UserCode.new(s_value: " printf(\"(%d, %d)\\n\", $X, $alias); "), + token_code: T::UserCode.new(s_value: " $$ = $X + $addend; "), nullable: false, - precedence_sym: grammar.find_symbol_by_s_value!("string"), - lineno: 24, + precedence_sym: grammar.find_symbol_by_s_value!("number"), + lineno: 23, ), Rule.new( id: 2, lhs: grammar.find_symbol_by_s_value!("program"), rhs: [ - grammar.find_symbol_by_s_value!("pair_number_string"), + grammar.find_symbol_by_s_value!("plus_summand"), ], lhs_tag: nil, - token_code: T::UserCode.new(s_value: " printf(\"pair odd even\\n\"); "), + token_code: T::UserCode.new(s_value: " printf(\"plus number\\n\"); "), nullable: false, precedence_sym: nil, - lineno: 24, + lineno: 23, ), ]) end From db76b6317eeb78b501b8ceb2d36f46e6f12c5f56 Mon Sep 17 00:00:00 2001 From: ydah Date: Sun, 26 May 2024 23:55:57 +0900 Subject: [PATCH 3/3] Fix incorrect test cases It is correct to specify a Named Reference for the parameter. --- .../with_action_and_named_references.y | 5 ++-- spec/lrama/parser_spec.rb | 24 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/spec/fixtures/parameterizing_rules/user_defined/with_action_and_named_references.y b/spec/fixtures/parameterizing_rules/user_defined/with_action_and_named_references.y index e68da1fe..698ad7bf 100644 --- a/spec/fixtures/parameterizing_rules/user_defined/with_action_and_named_references.y +++ b/spec/fixtures/parameterizing_rules/user_defined/with_action_and_named_references.y @@ -13,14 +13,13 @@ static int yyerror(YYLTYPE *loc, const char *str); } %token number -%token summand -%rule plus(X): X '+' number[addend] { $$ = $X + $addend; } +%rule sum(X, Y) : X[summand] '+' Y[addend] { $$ = $summand + $addend; } ; %% -program : plus(summand) { printf("plus number\n"); } +program : sum(number, number) { printf("sum number\n"); } ; %% diff --git a/spec/lrama/parser_spec.rb b/spec/lrama/parser_spec.rb index f03322cd..d5fb8352 100644 --- a/spec/lrama/parser_spec.rb +++ b/spec/lrama/parser_spec.rb @@ -1692,9 +1692,9 @@ it "expands parameterizing rules" do expect(grammar.nterms.sort_by(&:number)).to match_symbols([ - Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 0, nullable: false), - Sym.new(id: T::Ident.new(s_value: "plus_summand"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 1, nullable: false), - Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 8, tag: nil, term: false, token_id: 2, nullable: false), + Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 0, nullable: false), + Sym.new(id: T::Ident.new(s_value: "sum_number_number"), alias_name: nil, number: 6, tag: T::Tag.new(s_value: ""), term: false, token_id: 1, nullable: false), + Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 2, nullable: false), ]) expect(grammar.rules).to eq([ @@ -1708,33 +1708,33 @@ token_code: nil, nullable: false, precedence_sym: grammar.find_symbol_by_s_value!("YYEOF"), - lineno: 23, + lineno: 22, ), Rule.new( id: 1, - lhs: grammar.find_symbol_by_s_value!("plus_summand"), + lhs: grammar.find_symbol_by_s_value!("sum_number_number"), rhs: [ - grammar.find_symbol_by_s_value!("summand"), + grammar.find_symbol_by_s_value!("number"), grammar.find_symbol_by_s_value!("'+'"), grammar.find_symbol_by_s_value!("number") ], - lhs_tag: nil, - token_code: T::UserCode.new(s_value: " $$ = $X + $addend; "), + lhs_tag: T::Tag.new(s_value: ""), + token_code: T::UserCode.new(s_value: " $$ = $summand + $addend; "), nullable: false, precedence_sym: grammar.find_symbol_by_s_value!("number"), - lineno: 23, + lineno: 22, ), Rule.new( id: 2, lhs: grammar.find_symbol_by_s_value!("program"), rhs: [ - grammar.find_symbol_by_s_value!("plus_summand"), + grammar.find_symbol_by_s_value!("sum_number_number"), ], lhs_tag: nil, - token_code: T::UserCode.new(s_value: " printf(\"plus number\\n\"); "), + token_code: T::UserCode.new(s_value: " printf(\"sum number\\n\"); "), nullable: false, precedence_sym: nil, - lineno: 23, + lineno: 22, ), ]) end