Skip to content

Commit

Permalink
Change to embed #include of header files when they are specified
Browse files Browse the repository at this point in the history
  • Loading branch information
ydah committed Oct 5, 2023
1 parent 26c8b37 commit 5bd0c87
Show file tree
Hide file tree
Showing 11 changed files with 1,997 additions and 55 deletions.
2 changes: 1 addition & 1 deletion lib/lrama/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def run(argv)
Report::Duration.enable if options.trace_opts[:time]

warning = Lrama::Warning.new
grammar = Lrama::Parser.new(options.y.read).parse
grammar = Lrama::Parser.new(options.y.read, options.header_file).parse
options.y.close if options.y != STDIN
states = Lrama::States.new(grammar, warning, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure]))
states.compute
Expand Down
9 changes: 7 additions & 2 deletions lib/lrama/lexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ class Lexer
attr_reader :prologue, :bison_declarations, :grammar_rules, :epilogue,
:bison_declarations_tokens, :grammar_rules_tokens

def initialize(text)
def initialize(text, header_file)
@text = text
@header_path = header_file ? header_file.sub("./", "") : nil
@state = Initial
# Array of texts
@prologue = []
Expand Down Expand Up @@ -60,7 +61,11 @@ def lex_text
# Skip until "%{"
if string == "%{\n"
@state = Prologue
@prologue << ["", lineno]
if @header_path
@prologue << ["#include \"#{@header_path}\"\n", lineno]
else
@prologue << ["", lineno]
end
next
end
when Prologue
Expand Down
5 changes: 3 additions & 2 deletions lib/lrama/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ class Parser

T = Lrama::Lexer::Token

def initialize(text)
def initialize(text, header_file)
@text = text
@header_file = header_file
end

def parse
report_duration(:parse) do
lexer = Lexer.new(@text)
lexer = Lexer.new(@text, @header_file)
grammar = Grammar.new
process_prologue(grammar, lexer)
parse_bison_declarations(TokenScanner.new(lexer.bison_declarations_tokens), grammar)
Expand Down
2 changes: 0 additions & 2 deletions sample/calc.y
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
#include <stdlib.h>
#include <ctype.h>

#include "calc.h"

static int yylex(YYSTYPE *val, YYLTYPE *loc);
static int yyerror(YYLTYPE *loc, const char *str);
%}
Expand Down
3 changes: 0 additions & 3 deletions sample/parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

%{
// Prologue

#include "y.tab.h"

static enum yytokentype yylex(YYSTYPE *lval, YYLTYPE *yylloc);
static void yyerror(YYLTYPE *yylloc, const char *msg);

Expand Down
6 changes: 3 additions & 3 deletions spec/lrama/context_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
describe "basic" do
it do
y = File.read(fixture_path("context/basic.y"))
grammar = Lrama::Parser.new(y).parse
grammar = Lrama::Parser.new(y, nil).parse
states = Lrama::States.new(grammar, warning)
states.compute
context = Lrama::Context.new(states)
Expand Down Expand Up @@ -181,7 +181,7 @@
%%
INPUT

grammar = Lrama::Parser.new(y).parse
grammar = Lrama::Parser.new(y, nil).parse
states = Lrama::States.new(grammar, warning)
states.compute
context = Lrama::Context.new(states)
Expand Down Expand Up @@ -230,7 +230,7 @@
%%
INPUT

grammar = Lrama::Parser.new(y).parse
grammar = Lrama::Parser.new(y, nil).parse
states = Lrama::States.new(grammar, warning)
states.compute
context = Lrama::Context.new(states)
Expand Down
8 changes: 4 additions & 4 deletions spec/lrama/counterexamples_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
end

it "build counterexamples of S/R conflicts" do
grammar = Lrama::Parser.new(y).parse
grammar = Lrama::Parser.new(y, nil).parse
states = Lrama::States.new(grammar, warning)
states.compute
counterexamples = Lrama::Counterexamples.new(states)
Expand Down Expand Up @@ -249,7 +249,7 @@
end

it "build counterexamples of R/R conflicts" do
grammar = Lrama::Parser.new(y).parse
grammar = Lrama::Parser.new(y, nil).parse
states = Lrama::States.new(grammar, warning)
states.compute
counterexamples = Lrama::Counterexamples.new(states)
Expand Down Expand Up @@ -326,7 +326,7 @@
end

it "build counterexamples of S/R conflicts" do
grammar = Lrama::Parser.new(y).parse
grammar = Lrama::Parser.new(y, nil).parse
states = Lrama::States.new(grammar, warning)
states.compute
counterexamples = Lrama::Counterexamples.new(states)
Expand Down Expand Up @@ -407,7 +407,7 @@
end

it "build counterexamples of S/R and R/R conflicts" do
grammar = Lrama::Parser.new(y).parse
grammar = Lrama::Parser.new(y, nil).parse
states = Lrama::States.new(grammar, warning)
states.compute
counterexamples = Lrama::Counterexamples.new(states)
Expand Down
93 changes: 88 additions & 5 deletions spec/lrama/lexer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
describe '#lex' do
it "basic" do
y = File.read(fixture_path("common/basic.y"))
lexer = Lrama::Lexer.new(y)
lexer = Lrama::Lexer.new(y, nil)

expect(lexer.prologue.first[1]).to eq(7)
expect(lexer.prologue.map(&:first).join).to eq(<<~TEXT)
Expand Down Expand Up @@ -269,7 +269,7 @@ class : keyword_class tSTRING keyword_end %prec tPLUS

it "nullable" do
y = File.read(fixture_path("common/nullable.y"))
lexer = Lrama::Lexer.new(y)
lexer = Lrama::Lexer.new(y, nil)

expect(lexer.grammar_rules_tokens).to eq([
T.new(type: T::Ident_Colon, s_value: "program"),
Expand Down Expand Up @@ -335,7 +335,7 @@ class : keyword_class tSTRING keyword_end %prec tPLUS
;
%%
INPUT
lexer = Lrama::Lexer.new(y)
lexer = Lrama::Lexer.new(y, nil)
user_codes = lexer.grammar_rules_tokens.select do |t|
t.type == T::User_code
end
Expand Down Expand Up @@ -389,7 +389,7 @@ class : keyword_class tSTRING keyword_end %prec tPLUS
;
%%
INPUT
lexer = Lrama::Lexer.new(y)
lexer = Lrama::Lexer.new(y, nil)

expect(lexer.grammar_rules_tokens).to eq([
T.new(type: T::Ident_Colon, s_value: "line"),
Expand Down Expand Up @@ -457,7 +457,7 @@ class : keyword_class tSTRING keyword_end %prec tPLUS
;
%%
INPUT
lexer = Lrama::Lexer.new(y)
lexer = Lrama::Lexer.new(y, nil)
user_codes = lexer.grammar_rules_tokens.select do |t|
t.type == T::User_code
end
Expand All @@ -475,5 +475,88 @@ class : keyword_class tSTRING keyword_end %prec tPLUS
expect(user_codes.map(&:s_value)).to eq([expected])
end
end

describe "include header" do
context "when header is specified" do
it "parses correctly" do
y = <<~INPUT
%{
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
static int yylex(YYSTYPE *val, YYLTYPE *loc);
static int yyerror(YYLTYPE *loc, const char *str);
%}
%union {
int i;
}
%%
program : expr
;
%%
INPUT

lexer = Lrama::Lexer.new(y, "./test.h")
expect(lexer.prologue).to eq(
[
["#include \"test.h\"\n", 1],
[" #include <stdio.h>\n", 2],
[" #include <stdlib.h>\n", 3],
[" #include <ctype.h>\n", 4],
["\n", 5],
[" static int yylex(YYSTYPE *val, YYLTYPE *loc);\n", 6],
[" static int yyerror(YYLTYPE *loc, const char *str);\n", 7],
["", 8]
]
)
end
end

context "when header is not specified" do
context "when header is specified" do
it "parses correctly" do
y = <<~INPUT
%{
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
static int yylex(YYSTYPE *val, YYLTYPE *loc);
static int yyerror(YYLTYPE *loc, const char *str);
%}
%union {
int i;
}
%%
program : expr
;
%%
INPUT
lexer = Lrama::Lexer.new(y, nil)
expect(lexer.prologue).to eq(
[
["", 1],
[" #include <stdio.h>\n", 2],
[" #include <stdlib.h>\n", 3],
[" #include <ctype.h>\n", 4],
["\n", 5],
[" static int yylex(YYSTYPE *val, YYLTYPE *loc);\n", 6],
[" static int yyerror(YYLTYPE *loc, const char *str);\n", 7],
["", 8]
]
)
end
end
end
end
end
end
Loading

0 comments on commit 5bd0c87

Please sign in to comment.