Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions lib/lrama/grammar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ class Grammar
attr_accessor :expect #: Integer
attr_accessor :printers #: Array[Printer]
attr_accessor :error_tokens #: Array[ErrorToken]
attr_accessor :lex_param #: String
attr_accessor :parse_param #: String
attr_reader :lex_params #: Array[String]
attr_reader :parse_params #: Array[String]
attr_accessor :initial_action #: Grammar::Code::InitialActionCode
attr_accessor :after_shift #: Lexer::Token::Base
attr_accessor :before_reduce #: Lexer::Token::Base
Expand Down Expand Up @@ -119,6 +119,8 @@ def initialize(rule_counter, midrule_action_counter, locations, define = {})
@printers = []
@destructors = []
@error_tokens = []
@lex_params = []
@parse_params = []
@symbols_resolver = Grammar::Symbols::Resolver.new
@types = []
@rule_builders = []
Expand Down Expand Up @@ -335,16 +337,16 @@ def _evaluate_nodes
when Node::ParamDecl
node.params.each do |param|
code = Grammar::Code::NoReferenceCode.new(type: :param, token_code: param).token_code.s_value
self.lex_param = code
self.parse_param = code
lex_params << code
parse_params << code
end
when Node::LexParamDecl
node.params.each do |param|
self.lex_param = Grammar::Code::NoReferenceCode.new(type: :lex_param, token_code: param).token_code.s_value
lex_params << Grammar::Code::NoReferenceCode.new(type: :lex_param, token_code: param).token_code.s_value
end
when Node::ParseParamDecl
node.params.each do |param|
self.parse_param = Grammar::Code::NoReferenceCode.new(type: :parse_param, token_code: param).token_code.s_value
parse_params << Grammar::Code::NoReferenceCode.new(type: :parse_param, token_code: param).token_code.s_value
end
when Node::UnionDecl
self.set_union(
Expand Down
36 changes: 9 additions & 27 deletions lib/lrama/output.rb
Original file line number Diff line number Diff line change
Expand Up @@ -265,24 +265,16 @@ def omit_blanks(param)

# b4_parse_param
def parse_param
if @grammar.parse_param
omit_blanks(@grammar.parse_param)
else
""
end
@grammar.parse_params.map { |param| omit_blanks(param) }.join(", ")
end

def lex_param
if @grammar.lex_param
omit_blanks(@grammar.lex_param)
else
""
end
@grammar.lex_params.map { |param| omit_blanks(param) }.join(", ")
end

# b4_user_formals
def user_formals
if @grammar.parse_param
if @grammar.parse_params.any?
", #{parse_param}"
else
""
Expand All @@ -291,7 +283,7 @@ def user_formals

# b4_user_args
def user_args
if @grammar.parse_param
if @grammar.parse_params.any?
", #{parse_param_name}"
else
""
Expand All @@ -303,19 +295,11 @@ def extract_param_name(param)
end

def parse_param_name
if @grammar.parse_param
extract_param_name(parse_param)
else
""
end
@grammar.parse_params.map { |param| extract_param_name(param) }.join(", ")
end

def lex_param_name
if @grammar.lex_param
extract_param_name(lex_param)
else
""
end
@grammar.lex_params.map { |param| extract_param_name(param) }.join(", ")
end

# b4_parse_param_use
Expand All @@ -325,9 +309,7 @@ def parse_param_use(val, loc)
YY_USE (#{loc});
STR

if @grammar.parse_param
str << " YY_USE (#{parse_param_name});"
end
str << @grammar.parse_params.map { |param| " YY_USE (#{extract_param_name(param)});" }.join("\n")

str
end
Expand All @@ -337,7 +319,7 @@ def yylex_formals
ary = ["&yylval"]
ary << "&yylloc" if @grammar.locations

if @grammar.lex_param
if @grammar.lex_params.any?
ary << lex_param_name
end

Expand All @@ -357,7 +339,7 @@ def table_value_equals(table, value, literal, symbol)
def yyerror_args
ary = ["&yylloc"]

if @grammar.parse_param
if @grammar.parse_params.any?
ary << parse_param_name
end

Expand Down
4 changes: 2 additions & 2 deletions sig/generated/lrama/grammar.rbs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion spec/fixtures/integration/params.l
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <stdlib.h>
#include "params.h"

#define YY_DECL int yylex (YYSTYPE *yylval, YYLTYPE *yylloc, int parser_params)
#define YY_DECL int yylex (YYSTYPE *yylval, YYLTYPE *yylloc, int lexer_value, int shared, int offset, int *errors)

int yycolumn = 0;

Expand All @@ -23,6 +23,8 @@ NUMBER [0-9]+
%%

{NUMBER} {
if (lexer_value != 7 || shared != 5 || offset != 11 || *errors)
return YYUNDEF;
yylval->val = atoi(yytext);
return NUM;
}
Expand Down
30 changes: 21 additions & 9 deletions spec/fixtures/integration/params.y
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@
#define YYDEBUG 1
#include <stdio.h>

#define YY_LOCATION_PRINT(File, loc, p) ((void) 0)
#define YY_LOCATION_PRINT(File, loc, ...) ((void) 0)

#define YY_DECL yylex (YYSTYPE *lval, YYLTYPE *yylloc, int parser_params)
#define YY_DECL yylex (YYSTYPE *lval, YYLTYPE *yylloc, int lexer_value, int shared, int offset, int *errors)

#include "params.h"
#include "params-lexer.h"

extern int yylex(YYSTYPE *lval, YYLTYPE *yylloc, int parser_params);
static int yyerror(YYLTYPE *loc, int parse_param, const char *str);
static int lexer_value = 7;
extern int yylex(YYSTYPE *lval, YYLTYPE *yylloc, int lexer_value, int shared, int offset, int *errors);
static int yyerror(YYLTYPE *loc, int parser_value, int shared, int offset, int *errors, const char *str);

%}

%param {int parse_param}
%lex-param {int lexer_value}
%parse-param {int parser_value}
%param {int shared} {int offset}
%param {int *errors}

%union {
int val;
Expand All @@ -30,7 +34,11 @@ static int yyerror(YYLTYPE *loc, int parse_param, const char *str);
%%

program : /* empty */
| expr { printf("=> %d", $1); }
| expr {
if (parser_value != 3 || shared != 5 || offset != 11 || *errors)
YYABORT;
printf("=> %d", $1);
}
;
expr : NUM
| expr '+' expr { $$ = $1 + $3; }
Expand All @@ -42,19 +50,23 @@ expr : NUM

%%

static int yyerror(YYLTYPE *loc, int parse_param, const char *str) {
static int yyerror(YYLTYPE *loc, int parser_value, int shared, int offset, int *errors, const char *str) {
if (parser_value == 3 && shared == 5 && offset == 11)
++*errors;
fprintf(stderr, "parse error: %s\\n", str);
return 0;
}

int main(int argc, char *argv[]) {
int errors = 0;
if (argc == 2) {
yy_scan_string(argv[1]);
}

if (yyparse(0)) {
if (yyparse(3, 5, 11, &errors)) {
printf("errors: %d", errors);
fprintf(stderr, "syntax error\n");
return 1;
}
return 0;
return errors != 0;
}
6 changes: 5 additions & 1 deletion spec/lrama/integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,14 @@ def generate_object(grammar_file_path, c_path, obj_path, command_args: [])
test_parser("contains_at_reference", "", "")
end

describe "YYDEBUG and %param are enabled" do
describe "YYDEBUG and multiple parameters are enabled" do
it "returns 9 for '(1+2)*3'" do
test_parser("params", "(1+2)*3", "=> 9")
end

it "passes all parser parameters to yyerror" do
test_parser("params", "(1+)", "errors: 1", expect_success: false)
end
end

describe "named references" do
Expand Down
Loading
Loading