Skip to content

Commit

Permalink
Add support for Named References for actions of rhs in Parameterizing…
Browse files Browse the repository at this point in the history
… rules
  • Loading branch information
ydah committed May 1, 2024
1 parent 595472f commit 45f271d
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 1 deletion.
13 changes: 13 additions & 0 deletions lib/lrama/grammar/parameterizing_rule/rhs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ def initialize
@user_code = nil
@precedence_sym = nil
end

def resolve_user_code(bindings)
return unless user_code

code = user_code.s_value
symbols.each do |sym|
resolved_sym = bindings.resolve_symbol(sym)
if resolved_sym != sym
code = code.gsub(/\$#{sym.s_value}/, "$#{resolved_sym.s_value}")
end
end
Lrama::Lexer::Token::UserCode.new(s_value: code, location: user_code.location)
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/lrama/grammar/rule_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def process_rhs(parameterizing_rule_resolver)
r.symbols.each { |sym| rule_builder.add_rhs(bindings.resolve_symbol(sym)) }
rule_builder.line = line
rule_builder.precedence_sym = r.precedence_sym
rule_builder.user_code = r.user_code
rule_builder.user_code = r.resolve_user_code(bindings)
rule_builder.complete_input
rule_builder.setup_rules(parameterizing_rule_resolver)
@rule_builders_for_parameterizing_rules << rule_builder
Expand Down
1 change: 1 addition & 0 deletions sig/lrama/grammar/parameterizing_rule/rhs.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module Lrama
attr_reader precedence_sym: Lexer::Token?

def initialize: () -> void
def resolve_user_code: (Grammar::Binding bindings) -> Lexer::Token::UserCode?
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* This is comment for this file.
*/

%{
// Prologue
static int yylex(YYSTYPE *val, YYLTYPE *loc);
static int yyerror(YYLTYPE *loc, const char *str);
%}

%union {
int i;
char *s;
}

%token <i> number
%token <s> string

%rule pair(X, Y): X ',' Y { printf("(%d, %d)\n", $X, $2); }
;

%%

program : pair(number, string) { printf("pair odd even\n"); }
;

%%

static int yylex(YYSTYPE *yylval, YYLTYPE *loc)
{
return 0;
}

static int yyerror(YYLTYPE *loc, const char *str)
{
return 0;
}

int main(int argc, char *argv[])
{
}
53 changes: 53 additions & 0 deletions spec/lrama/parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1612,6 +1612,59 @@
),
])
end

context "with named references" do
let(:path) { "parameterizing_rules/user_defined/with_action_and_named_references.y" }

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: "program"), alias_name: nil, number: 8, tag: nil, term: false, token_id: 2, nullable: false),
])

expect(grammar.rules).to eq([
Rule.new(
id: 0,
lhs: grammar.find_symbol_by_s_value!("$accept"),
rhs: [
grammar.find_symbol_by_s_value!("program"),
grammar.find_symbol_by_s_value!("YYEOF"),
],
token_code: nil,
nullable: false,
precedence_sym: grammar.find_symbol_by_s_value!("YYEOF"),
lineno: 24,
),
Rule.new(
id: 1,
lhs: grammar.find_symbol_by_s_value!("pair_number_string"),
rhs: [
grammar.find_symbol_by_s_value!("number"),
grammar.find_symbol_by_number!(5),
grammar.find_symbol_by_s_value!("string")
],
lhs_tag: nil,
token_code: T::UserCode.new(s_value: " printf(\"(%d, %d)\\n\", $number, $2); "),
nullable: false,
precedence_sym: grammar.find_symbol_by_s_value!("string"),
lineno: 24,
),
Rule.new(
id: 2,
lhs: grammar.find_symbol_by_s_value!("program"),
rhs: [
grammar.find_symbol_by_s_value!("pair_number_string"),
],
lhs_tag: nil,
token_code: T::UserCode.new(s_value: " printf(\"pair odd even\\n\"); "),
nullable: false,
precedence_sym: nil,
lineno: 24,
),
])
end
end
end

context "when nested rules" do
Expand Down

0 comments on commit 45f271d

Please sign in to comment.