From d684d38dbfc9ff608ea45c8fc3a9115ed6d4e8cb Mon Sep 17 00:00:00 2001 From: ydah Date: Tue, 2 Sep 2025 21:46:29 +0900 Subject: [PATCH] Add support for error handling for missing comment end MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Example: ```yacc %{ // Prologue %} %% foo: "baz" ; %% /* This is a comment ``` Bison: ``` tmp/missing.y:8.1-9.0: error: missing ‘*/’ at end of file 8 | /* This is a comment | ^~~~~~~~~~~~~~~~~~~~ ``` Lrama: ``` # No error ``` --- lib/lrama/lexer.rb | 23 +++++++++++++++++++++++ spec/lrama/lexer_spec.rb | 14 ++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/lib/lrama/lexer.rb b/lib/lrama/lexer.rb index bd6e79bf..0073916f 100644 --- a/lib/lrama/lexer.rb +++ b/lib/lrama/lexer.rb @@ -157,6 +157,28 @@ def lex_c_code until @scanner.eos? do case + when @scanner.check(/\/\*/) + start_line = @line + start_column = column + + @scanner.scan(/\/\*/) + comment_start = @scanner.matched + + comment_location = Location.new( + grammar_file: @grammar_file, + first_line: start_line, first_column: start_column, + last_line: @line, last_column: column + ) + + comment_body = @scanner.scan_until(/\*\//) + + if comment_body + chunk = comment_start + comment_body + code += chunk + chunk.count("\n").times { newline } + else + raise ParseError, comment_location.generate_error_message('Missing ‘*/’ at end of file') # steep:ignore + end when @scanner.scan(/{/) code += @scanner.matched nested += 1 @@ -202,6 +224,7 @@ def lex_comment newline end end + raise "Unterminated comment." end # @rbs () -> void diff --git a/spec/lrama/lexer_spec.rb b/spec/lrama/lexer_spec.rb index 05173778..1bd8297f 100644 --- a/spec/lrama/lexer_spec.rb +++ b/spec/lrama/lexer_spec.rb @@ -414,6 +414,20 @@ end end + context 'missing_comment_end.y' do + it do + grammar_file = Lrama::Lexer::GrammarFile.new("invalid.y", "/* missing") + lexer = Lrama::Lexer.new(grammar_file) + lexer.status = :c_declaration + + expect { lexer.next_token }.to raise_error(ParseError, <<~ERROR) + invalid.y:1:0: Missing ‘*/’ at end of file + /* missing + ^^ + ERROR + end + end + it 'lex a line comment without newline' do grammar_file = Lrama::Lexer::GrammarFile.new("comment.y", "// foo") lexer = Lrama::Lexer.new(grammar_file)