Skip to content

Commit

Permalink
Merge pull request #71 from yui-knk/error_recover_test
Browse files Browse the repository at this point in the history
Add an integration test for error recovery
  • Loading branch information
yui-knk committed Aug 6, 2023
2 parents c5f7d30 + 57e119d commit 08ebe45
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 3 deletions.
2 changes: 1 addition & 1 deletion lib/lrama/grammar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def add_printer(ident_or_tags:, code:, lineno:)
end

def add_error_token(ident_or_tags:, code:, lineno:)
@error_tokens << ErrorToken.new(ident_or_tags, code, lineno)
@error_tokens << ErrorToken.new(ident_or_tags: ident_or_tags, code: code, lineno: lineno)
end

def add_term(id:, alias_name: nil, tag: nil, token_id: nil, replace: false)
Expand Down
58 changes: 56 additions & 2 deletions spec/lrama/integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,26 @@

RSpec.describe "integration" do
module IntegrationHelper
def test_rules(rules, input, expected)
def test_rules(rules, input, expected, command_args: [], debug: false)
cases = input.each_with_index.map do |(token, union, semantic_value), i|
str = ""
str << " case #{i}:\n"
str << " yylval->#{union} = #{semantic_value};\n" if union && semantic_value
str << " return #{token};\n"
end.join("\n")

yydebug_macro = ''
yydebug = ''

if debug
yydebug_macro = '#define YYDEBUG 1'
yydebug = 'yydebug = 1;'
command_args << "--report=all"
end

grammar = <<~Grammar
%{
#{yydebug_macro}
#include <stdio.h>
#include "test.h"
Expand Down Expand Up @@ -42,6 +52,7 @@ def test_rules(rules, input, expected)
}
int main() {
#{yydebug}
yyparse();
return 0;
}
Expand All @@ -54,7 +65,7 @@ def test_rules(rules, input, expected)
c_path = File.dirname(f.path) + "/test.c"
obj_path = File.dirname(f.path) + "/test"

Lrama::Command.new(%W[-d #{f.path} -o #{c_path}]).run
Lrama::Command.new(%W[-d -o #{c_path}] + command_args + %W[#{f.path}]).run

`gcc -Wall #{c_path} -o #{obj_path}`

Expand Down Expand Up @@ -140,4 +151,47 @@ def test_rules(rules, input, expected)
Rules
end
end

# TODO: Add test case for "(1+2"
describe "error_recovery" do
it "returns 6 for '(1+)'" do
# (1+) #=> 101
# '100' is complemented
input = [
%w['('],
%w[NUM val 1],
%w['+'],
%w[')'],
]

test_rules(<<~Rules, input, "=> 101", command_args: %W[-e])
%union {
int val;
}
%token <val> NUM
%type <val> expr
%left '+' '-'
%left '*' '/'
%error-token {
$$ = 100;
} NUM
%%
program : { (void)yynerrs; }
| expr { printf("=> %d", $1); }
;
expr : NUM
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }
| '(' expr ')' { $$ = $2; }
;
%%
Rules
end
end
end

0 comments on commit 08ebe45

Please sign in to comment.