Allow multiple lexer modes to be specified for a lexer pattern - close #35

This commit is contained in:
josh committed 2025-03-11 20:40:10 -04:00
1 parent 54bb3307cd
commit eb9d9026fc
11 files changed
+166 -30

No files matched your search

+6 -6
View File
@@ -151,30 +151,30 @@ EOF
o = grammar.patterns.find {|pattern| pattern.token == o}
expect(o).to_not be_nil
expect(o.mode).to be_nil
expect(o.modes).to be_empty
o = grammar.tokens.find {|token| token.name == "b"}
expect(o).to_not be_nil
o = grammar.patterns.find {|pattern| pattern.token == o}
expect(o).to_not be_nil
expect(o.mode).to eq "m1"
expect(o.modes).to eq Set["m1"]
o = grammar.patterns.find {|pattern| pattern.pattern == "foo"}
expect(o).to_not be_nil
expect(o.mode).to be_nil
expect(o.modes).to be_empty
o = grammar.patterns.find {|pattern| pattern.pattern == "bar"}
expect(o).to_not be_nil
expect(o.mode).to eq "m2"
expect(o.modes).to eq Set["m2"]
o = grammar.patterns.find {|pattern| pattern.pattern == "q"}
expect(o).to_not be_nil
expect(o.mode).to be_nil
expect(o.modes).to be_empty
o = grammar.patterns.find {|pattern| pattern.pattern == "r"}
expect(o).to_not be_nil
expect(o.mode).to eq "m3"
expect(o.modes).to eq Set["m3"]
end
it "allows assigning ptypes to tokens and rules" do
+56
View File
@@ -621,6 +621,62 @@ EOF
])
end
it "multiple lexer modes may apply to a pattern" do
case language
when "c"
write_grammar <<EOF
<<
#include <stdio.h>
>>
ptype char;
token abc;
token def;
default, identonly: token ident /[a-z]+/ <<
$$ = match[0];
$mode(default);
return $token(ident);
>>
token dot /\\./ <<
$mode(identonly);
>>
default, identonly: drop /\\s+/;
Start -> abc dot ident <<
printf("ident: %c\\n", $3);
>>
EOF
when "d"
write_grammar <<EOF
<<
import std.stdio;
>>
ptype char;
token abc;
token def;
default, identonly: token ident /[a-z]+/ <<
$$ = match[0];
$mode(default);
>>
token dot /\\./ <<
$mode(identonly);
>>
default, identonly: drop /\\s+/;
Start -> abc dot ident <<
writeln("ident: ", $3);
>>
EOF
end
run_propane(language: language)
compile("spec/test_lexer_multiple_modes.#{language}", language: language)
results = run_test
expect(results.status).to eq 0
verify_lines(results.stdout, [
"ident: d",
"pass1",
"ident: a",
"pass2",
])
end
it "executes user code associated with a parser rule" do
case language
when "c"
+20
View File
@@ -0,0 +1,20 @@
#include "testparser.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
int main()
{
char const * input = "abc.def";
p_context_t context;
p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_SUCCESS);
printf("pass1\n");
input = "abc . abc";
p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_SUCCESS);
printf("pass2\n");
return 0;
}
+21
View File
@@ -0,0 +1,21 @@
import testparser;
import std.stdio;
int main()
{
return 0;
}
unittest
{
string input = `abc.def`;
p_context_t context;
p_context_init(&context, input);
assert(p_parse(&context) == P_SUCCESS);
writeln("pass1");
input = `abc . abc`;
p_context_init(&context, input);
assert(p_parse(&context) == P_SUCCESS);
writeln("pass2");
}