Skip to content

Commit eb831ab

Browse files
authored
Merge pull request #542 from ratmice/cttest_grmtools_section
Add comma to grmtools section syntax
2 parents e2e5c5b + 5b7a126 commit eb831ab

File tree

23 files changed

+358
-40
lines changed

23 files changed

+358
-40
lines changed

.buildbot.sh

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,35 @@ export PATH=`pwd`/.cargo_install/bin/:$WASMTIME_HOME/bin:$PATH
1515

1616
# Install wasmtime once debian trixie is stablized
1717
# we can likely just use rust-wasmtime.
18+
#
19+
# Needed for wasm32-wasip2
1820
touch .wasmtime_profile
1921
if [ "X`which wasmtime`" = "X" ]; then
2022
PROFILE=".wasmtime_profile" bash -c 'curl https://wasmtime.dev/install.sh -sSf | bash'
2123
fi
2224
. ./.wasmtime_profile
2325

26+
# Needed for wasm32-unknown-unknown
2427
mkdir -p $NVM_DIR
2528
PROFILE=/dev/null bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash'
2629
. "$NVM_DIR/nvm.sh"
2730
# Download and install Node.js:
2831
nvm install 22
2932

30-
rustup target add wasm32-unknown-unknown
31-
rustup target add wasm32-wasip2
32-
cargo install wasm-bindgen-cli
33-
3433
cargo fmt --all -- --check
3534

3635
rustup toolchain install stable
3736
rustup default stable
3837

3938
cargo test
4039
cargo test --release
40+
41+
rustup target add wasm32-unknown-unknown
42+
cargo install wasm-bindgen-cli
4143
cargo test --target wasm32-unknown-unknown
44+
45+
rustup target add wasm32-wasip2
46+
cargo install workspace_runner
4247
cargo test --target wasm32-wasip2
4348

4449
cargo test --lib cfgrammar --features serde

.cargo/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[target.wasm32-wasip2]
2-
runner = "wasmtime run --dir ."
2+
runner = "workspace_runner --target wasm32-wasip2 --"
33

44
[target.wasm32-unknown-unknown]
55
# Provided by the crate wasm-bindgen-cli.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ lexer can be found in `src/calc.l`:
4646
and where the definitions for the parser can be found in `src/calc.y`:
4747

4848
```rust
49-
%grmtools{yacckind Grmtools}
49+
%grmtools{yacckind: Grmtools}
5050
%start Expr
5151
%avoid_insert "INT"
5252
%%

cfgrammar/src/lib/yacc/parser.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,14 @@ impl YaccParser {
455455
let (key_end_pos, key) = self.parse_name(i)?;
456456
i = self.parse_ws(key_end_pos, false)?;
457457
if key == "yacckind" {
458+
if let Some(j) = self.lookahead_is(":", i) {
459+
i = self.parse_ws(j, false)?;
460+
} else {
461+
return Err(YaccGrammarError {
462+
kind: YaccGrammarErrorKind::InvalidGrmtoolsHeaderKey,
463+
spans: vec![Span::new(i, i)],
464+
});
465+
}
458466
let val_end_pos = self.parse_yacckind(i, update_yacc_kind)?;
459467
if let Some(orig) = yacc_kind_key_span {
460468
let dupe = Span::new(key_start_pos, key_end_pos);
@@ -466,6 +474,12 @@ impl YaccParser {
466474
yacc_kind_key_span = Some(Span::new(key_start_pos, key_end_pos));
467475
i = self.parse_ws(val_end_pos, true)?;
468476
}
477+
if let Some(j) = self.lookahead_is(",", i) {
478+
i = self.parse_ws(j, true)?;
479+
continue;
480+
} else {
481+
break;
482+
}
469483
} else {
470484
return Err(YaccGrammarError {
471485
kind: YaccGrammarErrorKind::InvalidGrmtoolsHeaderKey,
@@ -2832,20 +2846,20 @@ B";
28322846
#[test]
28332847
fn test_grmtools_section_yacckinds() {
28342848
let srcs = [
2835-
"%grmtools{yacckind Original(NoAction)}
2849+
"%grmtools{yacckind: Original(NoAction)}
28362850
%%
28372851
Start: ;",
2838-
"%grmtools{yacckind YaccKind::Original(GenericParseTree)}
2852+
"%grmtools{yacckind: YaccKind::Original(GenericParseTree)}
28392853
%%
28402854
Start: ;",
2841-
"%grmtools{yacckind YaccKind::Original(yaccoriginalactionkind::useraction)}
2855+
"%grmtools{yacckind: YaccKind::Original(yaccoriginalactionkind::useraction)}
28422856
%actiontype ()
28432857
%%
28442858
Start: ;",
2845-
"%grmtools{yacckind Original(YACCOriginalActionKind::NoAction)}
2859+
"%grmtools{yacckind: Original(YACCOriginalActionKind::NoAction)}
28462860
%%
28472861
Start: ;",
2848-
"%grmtools{yacckind YaccKind::Grmtools}
2862+
"%grmtools{yacckind: YaccKind::Grmtools}
28492863
%%
28502864
Start -> () : ;",
28512865
];
@@ -2856,6 +2870,35 @@ B";
28562870
}
28572871
}
28582872

2873+
#[test]
2874+
fn test_grmtools_section_commas() {
2875+
// We can't actually test much here, because
2876+
// We don't have a second value to test.
2877+
//
2878+
// `RecoveryKind` seemed like an option for an additional value to allow,
2879+
// but that is part of `lrpar` which cfgrammar doesn't depend upon.
2880+
let src = r#"
2881+
%grmtools{
2882+
yacckind: YaccKind::Grmtools,
2883+
}
2884+
%%
2885+
Start -> () : ;
2886+
"#;
2887+
YaccParser::new(YaccKindResolver::NoDefault, src.to_string())
2888+
.parse()
2889+
.unwrap();
2890+
let src = r#"
2891+
%grmtools{
2892+
yacckind: YaccKind::Grmtools
2893+
}
2894+
%%
2895+
Start -> () : ;
2896+
"#;
2897+
YaccParser::new(YaccKindResolver::NoDefault, src.to_string())
2898+
.parse()
2899+
.unwrap();
2900+
}
2901+
28592902
#[test]
28602903
fn test_empty_production_spans_issue_473() {
28612904
let empty_prod_conflicts = [

doc/src/errorrecovery.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ make use of error recovery.
4949
A simple calculator grammar looks as follows:
5050

5151
```rust,noplaypen
52-
%grmtools{yacckind Grmtools}
52+
%grmtools{yacckind: Grmtools}
5353
%start Expr
5454
%%
5555
Expr -> u64:
@@ -182,7 +182,7 @@ We thus change the grammar so that inserted integers prevent evaluation from
182182
occurring:
183183

184184
```rust,noplaypen
185-
%grmtools{yacckind Grmtools}
185+
%grmtools{yacckind: Grmtools}
186186
%start Expr
187187
%%
188188
Expr -> Result<u64, ()>:

doc/src/lexextensions.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ other flags should specify their value immediately after the flag name.
1515

1616
```
1717
%grmtools {
18-
allow_wholeline_comments
19-
!octal
20-
size_limit 1024
18+
allow_wholeline_comments,
19+
!octal,
20+
size_limit: 1024,
2121
}
2222
%%
2323
. "rule"
@@ -56,7 +56,7 @@ The following flags can change the behavior to match posix lex more closely.
5656

5757
```
5858
%grmtools {
59-
!dot_matches_new_line
59+
!dot_matches_new_line,
6060
posix_escapes
6161
}
6262
%%

doc/src/quickstart.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ is lexed, but no lexemes are created from it.
101101

102102
Our initial version of calc.y looks as follows:
103103
```rust,noplaypen
104-
%grmtools{yacckind Grmtools}
104+
%grmtools{yacckind: Grmtools}
105105
%start Expr
106106
%%
107107
Expr -> Result<u64, ()>:

doc/src/yaccextensions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ But a default can be set or forced by using a `YaccKindResolver`.
1111
## Example
1212

1313
```
14-
%grmtools{yacckind Grmtools}
14+
%grmtools{yacckind: Grmtools}
1515
%%
1616
Start: ;
1717
```

lrlex/examples/calc_manual_lex/src/calc.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
%grmtools{yacckind Grmtools}
1+
%grmtools{yacckind: Grmtools}
22
%start Expr
33
%avoid_insert "INT"
44
%expect-unused Unmatched "UNMATCHED"

lrlex/src/lib/parser.rs

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,15 @@ where
304304
});
305305
}
306306
i = self.parse_spaces(i)?;
307+
if let Some(j) = self.lookahead_is(":", i) {
308+
i = j
309+
} else {
310+
return Err(LexBuildError {
311+
kind: LexErrorKind::InvalidGrmtoolsSectionValue,
312+
spans: vec![Span::new(i, i)],
313+
});
314+
}
315+
i = self.parse_spaces(i)?;
307316
let j = self.parse_digits(i)?;
308317
// This checks that the digits are valid numbers, but currently just returns `None`
309318
// when the values are actually out of range for that type. This could be improved.
@@ -351,11 +360,18 @@ where
351360
&mut grmtools_section_span_map,
352361
&mut grmtools_section_lex_flags,
353362
)?;
354-
if i == self.src.len() {
355-
return Err(self.mk_error(LexErrorKind::PrematureEnd, i));
363+
if let Some(j) = self.lookahead_is(",", i) {
364+
i = self.parse_ws(j)?;
365+
continue;
366+
} else {
367+
break;
356368
}
357369
}
358-
i = self.lookahead_is("}", i).unwrap();
370+
if let Some(j) = self.lookahead_is("}", i) {
371+
i = j
372+
} else {
373+
return Err(self.mk_error(LexErrorKind::PrematureEnd, i));
374+
}
359375
i = self.parse_ws(i)?;
360376
}
361377
grmtools_section_lex_flags.merge_from(&self.force_lex_flags);
@@ -864,7 +880,9 @@ mod test {
864880
.expect_err("Parsed ok while expecting error");
865881
assert_eq!(errs.len(), 1);
866882
let e = &errs[0];
867-
assert!(e.kind.is_same_kind(&kind));
883+
if !e.kind.is_same_kind(&kind) {
884+
panic!("expected {:?}.is_same_kind({:?})", &e.kind, &kind);
885+
}
868886
assert_eq!(
869887
e.spans()
870888
.iter()
@@ -1864,7 +1882,7 @@ b "A"
18641882
fn test_grmtools_section_fails() {
18651883
let src = r#"
18661884
%grmtools {
1867-
!unicode
1885+
!unicode,
18681886
unicode
18691887
}
18701888
%%
@@ -1879,8 +1897,8 @@ b "A"
18791897

18801898
let src = r#"
18811899
%grmtools {
1882-
size_limit 5
1883-
size_limit 6
1900+
size_limit: 5,
1901+
size_limit: 6,
18841902
}
18851903
%%
18861904
. "dot";
@@ -1894,7 +1912,7 @@ b "A"
18941912

18951913
let src = r#"
18961914
%grmtools {
1897-
!size_limit 5
1915+
!size_limit: 5,
18981916
}
18991917
%%
19001918
. "dot"
@@ -1906,6 +1924,22 @@ b "A"
19061924
3,
19071925
3,
19081926
);
1927+
// The following is missing comma separators for more than 2 elements
1928+
// This is to avoid parsing it as "key value" number of elements.
1929+
// However we actually error after the first element since the parser
1930+
// knows "case_insensitive" is a flag with no arguments.
1931+
let src = r#"
1932+
%grmtools {unicode, case_insensitive posix_escapes allow_comments}
1933+
%%
1934+
. "dot"
1935+
\n+ ;
1936+
"#;
1937+
LRNonStreamingLexerDef::<DefaultLexerTypes<u8>>::from_str(src).expect_error_at_line_col(
1938+
src,
1939+
LexErrorKind::PrematureEnd,
1940+
2,
1941+
38,
1942+
);
19091943
}
19101944

19111945
#[test]

lrpar/cttests/src/calc_nodefault_yacckind.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Test basic user actions using the calculator grammar
22
grammar: |
3-
%grmtools {yacckind Original(UserAction)}
3+
%grmtools {yacckind: Original(UserAction)}
44
%start Expr
55
%actiontype Result<u64, ()>
66
%avoid_insert 'INT'

lrpar/cttests/src/calc_wasm.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Test running on wasm targets
22
grammar: |
3-
%grmtools {yacckind Grmtools}
3+
%grmtools {yacckind: Grmtools}
44
%start Expr
55
%avoid_insert "INT"
66
%expect-unused Unmatched "UNMATCHED"

lrpar/cttests/src/cgen_helper.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ pub(crate) fn run_test_path<P: AsRef<Path>>(path: P) -> Result<(), Box<dyn std::
7979
// Create grammar files
8080
let base = path.file_stem().unwrap().to_str().unwrap();
8181
let mut pg = PathBuf::from(&out_dir);
82-
pg.push(format!("{}.y.rs", base));
82+
pg.push(format!("{}.test.y", base));
8383
fs::write(&pg, grm).unwrap();
8484
let mut pl = PathBuf::from(&out_dir);
85-
pl.push(format!("{}.l.rs", base));
85+
pl.push(format!("{}.test.l", base));
8686
fs::write(&pl, lex).unwrap();
8787

8888
// Build parser and lexer

0 commit comments

Comments
 (0)