diff --git a/lib/lrama/output.rb b/lib/lrama/output.rb index 5bc4d1ab..95747ce4 100644 --- a/lib/lrama/output.rb +++ b/lib/lrama/output.rb @@ -41,11 +41,8 @@ def self.erb(input) end end - def eval_template(file, path) - erb = self.class.erb(File.read(file)) - erb.filename = file - tmp = erb.result_with_hash(context: @context, output: self) - replace_special_variables(tmp, path) + def render_partial(file) + render_template(partial_file(file)) end def render @@ -354,6 +351,17 @@ def b4_cpp_guard__b4_spec_mapped_header_file private + def eval_template(file, path) + tmp = render_template(file) + replace_special_variables(tmp, path) + end + + def render_template(file) + erb = self.class.erb(File.read(file)) + erb.filename = file + erb.result_with_hash(context: @context, output: self) + end + def template_file File.join(template_dir, @template_name) end @@ -362,6 +370,10 @@ def header_template_file File.join(template_dir, "bison/yacc.h") end + def partial_file(file) + File.join(template_dir, file) + end + def template_dir File.expand_path("../../../template", __FILE__) end diff --git a/spec/lrama/output_spec.rb b/spec/lrama/output_spec.rb index 7a143244..91f1283c 100644 --- a/spec/lrama/output_spec.rb +++ b/spec/lrama/output_spec.rb @@ -6,17 +6,22 @@ out: out, output_file_path: "y.tab.c", template_name: "bison/yacc.c", - grammar_file_path: "parse.tmp.y", + grammar_file_path: grammar_file_path, header_out: header_out, - header_file_path: "y.tab.h", + header_file_path: header_file_path, context: context, grammar: grammar, ) } let(:out) { StringIO.new } let(:header_out) { StringIO.new } - let(:context) { double("context") } - let(:grammar) { double("grammar") } + let(:warning) { Lrama::Warning.new(StringIO.new) } + let(:text) { File.read(grammar_file_path) } + let(:grammar) { Lrama::Parser.new(text).parse } + let(:states) { s = Lrama::States.new(grammar, warning); s.compute; s } + let(:context) { Lrama::Context.new(states) } + let(:grammar_file_path) { fixture_path("common/basic.y") } + let(:header_file_path) { "y.tab.h" } describe "#parse_param" do it "returns declaration of parse param without blanks" do @@ -145,4 +150,51 @@ expect(output.lex_param_name).to eq("lex_param") end end + + describe "#render" do + context "header_file_path is specified" do + before do + output.render + out.rewind + header_out.rewind + end + + it "renders C file and header file" do + expect(out.size).not_to eq 0 + expect(header_out.size).not_to eq 0 + end + + it "doesn't include [@oline@] and [@ofile@] in files" do + o = out.read + h = header_out.read + + expect(o).not_to match /\[@oline@\]/ + expect(o).not_to match /\[@ofile@\]/ + expect(h).not_to match /\[@oline@\]/ + expect(h).not_to match /\[@ofile@\]/ + end + end + + context "header_file_path is not specified" do + let(:header_file_path) { nil } + + before do + output.render + out.rewind + header_out.rewind + end + + it "renders only C file" do + expect(out.size).not_to eq 0 + expect(header_out.size).to eq 0 + end + + it "doesn't include [@oline@] and [@ofile@] in a file" do + o = out.read + + expect(o).not_to match /\[@oline@\]/ + expect(o).not_to match /\[@ofile@\]/ + end + end + end end diff --git a/template/bison/_yacc.h b/template/bison/_yacc.h new file mode 100644 index 00000000..2af4d1e1 --- /dev/null +++ b/template/bison/_yacc.h @@ -0,0 +1,71 @@ +<%# b4_shared_declarations -%> + <%-# b4_cpp_guard_open([b4_spec_mapped_header_file]) -%> + <%- if output.spec_mapped_header_file -%> +#ifndef <%= output.b4_cpp_guard__b4_spec_mapped_header_file %> +# define <%= output.b4_cpp_guard__b4_spec_mapped_header_file %> + <%- end -%> + <%-# b4_declare_yydebug & b4_YYDEBUG_define -%> +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG && !defined(yydebug) +extern int yydebug; +#endif + <%-# b4_percent_code_get([[requires]]). %code is not supported -%> + + <%-# b4_token_enums_defines -%> +/* Token kinds. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { +<%= output.token_enums -%> + }; + typedef enum yytokentype yytoken_kind_t; +#endif + + <%-# b4_declare_yylstype -%> + <%-# b4_value_type_define -%> +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +union YYSTYPE +{ +#line <%= output.grammar.union.lineno %> "<%= output.grammar_file_path %>" +<%= output.grammar.union.braces_less_code %> +#line [@oline@] [@ofile@] + +}; +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + <%-# b4_location_type_define -%> +/* Location type. */ +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE YYLTYPE; +struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +}; +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + + + + <%-# b4_declare_yyerror_and_yylex. Not supported -%> + <%-# b4_declare_yyparse -%> +int yyparse (<%= output.parse_param %>); + + + <%-# b4_percent_code_get([[provides]]). %code is not supported -%> + <%-# b4_cpp_guard_close([b4_spec_mapped_header_file]) -%> + <%- if output.spec_mapped_header_file -%> +#endif /* !<%= output.b4_cpp_guard__b4_spec_mapped_header_file %> */ + <%- end -%> diff --git a/template/bison/yacc.c b/template/bison/yacc.c index 15abbe54..840afc22 100644 --- a/template/bison/yacc.c +++ b/template/bison/yacc.c @@ -106,77 +106,7 @@ <%- else -%> /* Use api.header.include to #include this header instead of duplicating it here. */ -<%# b4_shared_declarations -%> - <%-# b4_cpp_guard_open([b4_spec_mapped_header_file]) -%> - <%- if output.spec_mapped_header_file -%> -#ifndef <%= output.b4_cpp_guard__b4_spec_mapped_header_file %> -# define <%= output.b4_cpp_guard__b4_spec_mapped_header_file %> - <%- end -%> - <%-# b4_declare_yydebug & b4_YYDEBUG_define -%> -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG && !defined(yydebug) -extern int yydebug; -#endif - <%-# b4_percent_code_get([[requires]]). %code is not supported -%> - - <%-# b4_token_enums_defines -%> -/* Token kinds. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { -<%= output.token_enums -%> - }; - typedef enum yytokentype yytoken_kind_t; -#endif - - <%-# b4_declare_yylstype -%> - <%-# b4_value_type_define -%> -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -union YYSTYPE -{ -#line <%= output.grammar.union.lineno %> "<%= output.grammar_file_path %>" -<%= output.grammar.union.braces_less_code %> -#line [@oline@] [@ofile@] - -}; -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - <%-# b4_location_type_define -%> -/* Location type. */ -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE YYLTYPE; -struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -}; -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - - - - <%-# b4_declare_yyerror_and_yylex. Not supported -%> - <%-# b4_declare_yyparse -%> -int yyparse (<%= output.parse_param %>); - - - <%-# b4_percent_code_get([[provides]]). %code is not supported -%> - <%-# b4_cpp_guard_close([b4_spec_mapped_header_file]) -%> - <%- if output.spec_mapped_header_file -%> -#endif /* !<%= output.b4_cpp_guard__b4_spec_mapped_header_file %> */ - <%- end -%> +<%= output.render_partial("bison/_yacc.h") %> <%- end -%> <%# b4_declare_symbol_enum -%> /* Symbol kind. */ diff --git a/template/bison/yacc.h b/template/bison/yacc.h index 7cdeb81d..848dbf59 100644 --- a/template/bison/yacc.h +++ b/template/bison/yacc.h @@ -37,75 +37,4 @@ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ - -<%# b4_shared_declarations -%> - <%-# b4_cpp_guard_open([b4_spec_mapped_header_file]) -%> - <%- if output.spec_mapped_header_file -%> -#ifndef <%= output.b4_cpp_guard__b4_spec_mapped_header_file %> -# define <%= output.b4_cpp_guard__b4_spec_mapped_header_file %> - <%- end -%> - <%-# b4_declare_yydebug & b4_YYDEBUG_define -%> -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG && !defined(yydebug) -extern int yydebug; -#endif - <%-# b4_percent_code_get([[requires]]). %code is not supported -%> - - <%-# b4_token_enums_defines -%> -/* Token kinds. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { -<%= output.token_enums -%> - }; - typedef enum yytokentype yytoken_kind_t; -#endif - - <%-# b4_declare_yylstype -%> - <%-# b4_value_type_define -%> -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -union YYSTYPE -{ -#line <%= output.grammar.union.lineno %> "<%= output.grammar_file_path %>" -<%= output.grammar.union.braces_less_code %> -#line [@oline@] [@ofile@] - -}; -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - <%-# b4_location_type_define -%> -/* Location type. */ -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE YYLTYPE; -struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -}; -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - - - - <%-# b4_declare_yyerror_and_yylex. Not supported -%> - <%-# b4_declare_yyparse -%> -int yyparse (<%= output.parse_param %>); - - - <%-# b4_percent_code_get([[provides]]). %code is not supported -%> - <%-# b4_cpp_guard_close([b4_spec_mapped_header_file]) -%> - <%- if output.spec_mapped_header_file -%> -#endif /* !<%= output.b4_cpp_guard__b4_spec_mapped_header_file %> */ - <%- end -%> +<%= output.render_partial("bison/_yacc.h") %>