diff --git a/assets/parser.d.erb b/assets/parser.d.erb index c158be0..e44b3a2 100644 --- a/assets/parser.d.erb +++ b/assets/parser.d.erb @@ -186,11 +186,12 @@ class <%= @classname %> * Execute user code associated with a lexer pattern. * * @param code_id The ID of the user code block to execute. + * @param match Matched text for this pattern. * * @return Token ID to accept, or _TOKEN_COUNT if the user code does * not explicitly return a token. */ - private uint user_code(uint code_id) + private uint user_code(uint code_id, string match) { switch (code_id) { @@ -268,7 +269,7 @@ class <%= @classname %> uint token_to_accept = longest_match_info.token; if (longest_match_info.code_id != 0xFFFF_FFFFu) { - uint user_code_token = user_code(longest_match_info.code_id); + uint user_code_token = user_code(longest_match_info.code_id, m_input[m_input_position..(m_input_position + longest_match_info.length)]); /* A return of _TOKEN_COUNT from user_code() means * that the user code did not explicitly return a * token. So only override the token to return if the diff --git a/spec/propane_spec.rb b/spec/propane_spec.rb index e274543..0bed976 100644 --- a/spec/propane_spec.rb +++ b/spec/propane_spec.rb @@ -300,4 +300,21 @@ EOF expect(results.status).to_not eq 0 expect(results.stderr).to match %r{reduce/reduce conflict.*\(E\).*\(F\)} end + + it "provides matched text to user code blocks" do + write_grammar <> +Start -> id; +EOF + build_parser + compile("spec/test_lexer_match_text.d") + results = run + expect(results.status).to eq 0 + verify_lines(results.stdout, [ + "Matched token is identifier_123", + "pass1", + ]) + end end diff --git a/spec/test_lexer_match_text.d b/spec/test_lexer_match_text.d new file mode 100644 index 0000000..669757c --- /dev/null +++ b/spec/test_lexer_match_text.d @@ -0,0 +1,15 @@ +import testparser; +import std.stdio; + +int main() +{ + return 0; +} + +unittest +{ + string input = `identifier_123`; + auto parser = new Testparser.Parser(input); + assert(parser.parse() == true); + writeln("pass1"); +}