Skip to content

Commit

Permalink
Merge pull request ruby#382 from ydah/add-sequences
Browse files Browse the repository at this point in the history
Add sequences in Standard libraries
  • Loading branch information
yui-knk authored Mar 10, 2024
2 parents fd6f095 + 4a76a7d commit e09e1ea
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 0 deletions.
42 changes: 42 additions & 0 deletions lib/lrama/grammar/stdlib.y
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
**********************************************************************/

// -------------------------------------------------------------------
// Options

/*
* program: option(number)
*
Expand All @@ -21,6 +24,45 @@
| X
;

// -------------------------------------------------------------------
// Sequences

/*
* program: preceded(opening, X)
*
* =>
*
* program: preceded_opening_X
* preceded_opening_X: opening X
*/
%rule preceded(opening, X): opening X { $$ = $2; }
;

/*
* program: terminated(X, closing)
*
* =>
*
* program: terminated_X_closing
* terminated_X_closing: X closing
*/
%rule terminated(X, closing): X closing { $$ = $1; }
;

/*
* program: delimited(opening, X, closing)
*
* =>
*
* program: delimited_opening_X_closing
* delimited_opening_X_closing: opening X closing
*/
%rule delimited(opening, X, closing): opening X closing { $$ = $2; }
;

// -------------------------------------------------------------------
// Lists

/*
* program: list(number)
*
Expand Down
36 changes: 36 additions & 0 deletions spec/fixtures/parameterizing_rules/delimited.y
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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;
}

%token <i> number

%%

program : delimited('(', number, ')')
;

%%

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[])
{
}
36 changes: 36 additions & 0 deletions spec/fixtures/parameterizing_rules/preceded.y
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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;
}

%token <i> number

%%

program : preceded('(', number)
;

%%

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[])
{
}
36 changes: 36 additions & 0 deletions spec/fixtures/parameterizing_rules/terminated.y
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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;
}

%token <i> number

%%

program : terminated(number, ')')
;

%%

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

context "when preceded" do
let(:path) { "parameterizing_rules/preceded.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: "preceded_'('_number"), alias_name: nil, number: 6, tag: nil, 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([
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: 19,
),
Rule.new(
id: 1,
lhs: grammar.find_symbol_by_s_value!("preceded_'('_number"),
rhs: [
grammar.find_symbol_by_number!(4),
grammar.find_symbol_by_s_value!("number"),
],
token_code: T::UserCode.new(s_value: " $$ = $2; "),
nullable: false,
precedence_sym: grammar.find_symbol_by_s_value!("number"),
lineno: 19,
),
Rule.new(
id: 2,
lhs: grammar.find_symbol_by_s_value!("program"),
rhs: [
grammar.find_symbol_by_s_value!("preceded_'('_number"),
],
token_code: nil,
nullable: false,
precedence_sym: nil,
lineno: 19,
)
])
end
end

context "when terminated" do
let(:path) { "parameterizing_rules/terminated.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: "terminated_number_')'"), alias_name: nil, number: 6, tag: nil, 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([
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: 19,
),
Rule.new(
id: 1,
lhs: grammar.find_symbol_by_s_value!("terminated_number_')'"),
rhs: [
grammar.find_symbol_by_s_value!("number"),
grammar.find_symbol_by_number!(4),
],
token_code: T::UserCode.new(s_value: " $$ = $1; "),
nullable: false,
precedence_sym: grammar.find_symbol_by_number!(4),
lineno: 19,
),
Rule.new(
id: 2,
lhs: grammar.find_symbol_by_s_value!("program"),
rhs: [
grammar.find_symbol_by_s_value!("terminated_number_')'"),
],
token_code: nil,
nullable: false,
precedence_sym: nil,
lineno: 19,
)
])
end
end

context "when delimited" do
let(:path) { "parameterizing_rules/delimited.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: "delimited_'('_number_')'"), 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: 19,
),
Rule.new(
id: 1,
lhs: grammar.find_symbol_by_s_value!("delimited_'('_number_')'"),
rhs: [
grammar.find_symbol_by_number!(4),
grammar.find_symbol_by_s_value!("number"),
grammar.find_symbol_by_number!(5),
],
token_code: T::UserCode.new(s_value: " $$ = $2; "),
nullable: false,
precedence_sym: grammar.find_symbol_by_number!(5),
lineno: 19,
),
Rule.new(
id: 2,
lhs: grammar.find_symbol_by_s_value!("program"),
rhs: [
grammar.find_symbol_by_s_value!("delimited_'('_number_')'"),
],
token_code: nil,
nullable: false,
precedence_sym: nil,
lineno: 19,
)
])
end
end

context "when nonempty list" do
let(:path) { "parameterizing_rules/nonempty_list.y" }

Expand Down

0 comments on commit e09e1ea

Please sign in to comment.