Skip to content

Commit

Permalink
Merge pull request #408 from ydah/callee-side-tag
Browse files Browse the repository at this point in the history
Add support for the callee side tag specification of parameterizing rules
  • Loading branch information
yui-knk authored May 1, 2024
2 parents bf3a016 + 2bc3e03 commit 236c0f8
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 128 deletions.
5 changes: 3 additions & 2 deletions lib/lrama/grammar/parameterizing_rule/rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ module Lrama
class Grammar
class ParameterizingRule
class Rule
attr_reader :name, :parameters, :rhs_list, :required_parameters_count, :is_inline
attr_reader :name, :parameters, :rhs_list, :required_parameters_count, :tag, :is_inline

def initialize(name, parameters, rhs_list, is_inline: false)
def initialize(name, parameters, rhs_list, tag: nil, is_inline: false)
@name = name
@parameters = parameters
@rhs_list = rhs_list
@tag = tag
@is_inline = is_inline
@required_parameters_count = parameters.count
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 @@ -130,7 +130,7 @@ def process_rhs(parameterizing_rule_resolver)
@replaced_rhs << lhs_token
parameterizing_rule_resolver.created_lhs_list << lhs_token
parameterizing_rule.rhs_list.each do |r|
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, lhs_tag: token.lhs_tag)
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, lhs_tag: token.lhs_tag || parameterizing_rule.tag)
rule_builder.lhs = lhs_token
r.symbols.each { |sym| rule_builder.add_rhs(bindings.resolve_symbol(sym)) }
rule_builder.line = line
Expand Down
244 changes: 122 additions & 122 deletions lib/lrama/parser.rb

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,9 @@ rule

token_declaration: id int_opt alias { result = val }

rule_declaration: "%rule" IDENTIFIER "(" rule_args ")" ":" rule_rhs_list
rule_declaration: "%rule" IDENTIFIER "(" rule_args ")" tag_opt ":" rule_rhs_list
{
rule = Grammar::ParameterizingRule::Rule.new(val[1].s_value, val[3], val[6])
rule = Grammar::ParameterizingRule::Rule.new(val[1].s_value, val[3], val[7], tag: val[5])
@grammar.add_parameterizing_rule(rule)
}

Expand Down
3 changes: 2 additions & 1 deletion sig/lrama/grammar/parameterizing_rule/rule.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ module Lrama
attr_reader parameters: Array[Lexer::Token]
attr_reader rhs_list: Array[Grammar::ParameterizingRule::Rhs]
attr_reader required_parameters_count: Integer
attr_reader tag: Lexer::Token::Tag?
attr_reader is_inline: bool

def initialize: (String name, Array[Lexer::Token] parameters, Array[Grammar::ParameterizingRule::Rhs] rhs_list, ?is_inline: bool) -> void
def initialize: (String name, Array[Lexer::Token] parameters, Array[Grammar::ParameterizingRule::Rhs] rhs_list, ?tag: Lexer::Token::Tag, ?is_inline: bool) -> void
end
end
end
Expand Down
42 changes: 42 additions & 0 deletions spec/fixtures/parameterizing_rules/user_defined/with_tag.y
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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 with_tag(X) <i>: X { $$ = $1; }
;

%%

program : with_tag(number)
| with_tag(string) <s>
;

%%

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[])
{
}
74 changes: 74 additions & 0 deletions spec/lrama/parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,80 @@
end
end

context "with tag" do
let(:path) { "parameterizing_rules/user_defined/with_tag.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: 5, tag: nil, term: false, token_id: 0, nullable: false),
Sym.new(id: T::Ident.new(s_value: "with_tag_number"), alias_name: nil, number: 6, tag: T::Tag.new(s_value: "<i>"), 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),
Sym.new(id: T::Ident.new(s_value: "with_tag_string"), alias_name: nil, number: 8, tag: T::Tag.new(s_value: "<s>"), term: false, token_id: 3, 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!("with_tag_number"),
rhs: [
grammar.find_symbol_by_s_value!("number"),
],
lhs_tag: T::Tag.new(s_value: "<i>"),
token_code: T::UserCode.new(s_value: " $$ = $1; "),
nullable: false,
precedence_sym: grammar.find_symbol_by_s_value!("number"),
lineno: 24,
),
Rule.new(
id: 2,
lhs: grammar.find_symbol_by_s_value!("program"),
rhs: [
grammar.find_symbol_by_s_value!("with_tag_number"),
],
token_code: nil,
nullable: false,
precedence_sym: nil,
lineno: 24,
),
Rule.new(
id: 3,
lhs: grammar.find_symbol_by_s_value!("with_tag_string"),
rhs: [
grammar.find_symbol_by_s_value!("string"),
],
lhs_tag: T::Tag.new(s_value: "<s>"),
token_code: T::UserCode.new(s_value: " $$ = $1; "),
nullable: false,
precedence_sym: grammar.find_symbol_by_s_value!("string"),
lineno: 25,
),
Rule.new(
id: 4,
lhs: grammar.find_symbol_by_s_value!("program"),
rhs: [
grammar.find_symbol_by_s_value!("with_tag_string"),
],
token_code: nil,
nullable: false,
precedence_sym: nil,
lineno: 25,
),
])
end
end

context "when multi arguments" do
let(:path) { "parameterizing_rules/user_defined/multi_arguments.y" }

Expand Down

0 comments on commit 236c0f8

Please sign in to comment.