-
Notifications
You must be signed in to change notification settings - Fork 33
Add comma to grmtools section syntax #542
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -304,6 +304,15 @@ where | |
}); | ||
} | ||
i = self.parse_spaces(i)?; | ||
if let Some(j) = self.lookahead_is(":", i) { | ||
i = j | ||
} else { | ||
return Err(LexBuildError { | ||
kind: LexErrorKind::InvalidGrmtoolsSectionValue, | ||
spans: vec![Span::new(i, i)], | ||
}); | ||
} | ||
i = self.parse_spaces(i)?; | ||
let j = self.parse_digits(i)?; | ||
// This checks that the digits are valid numbers, but currently just returns `None` | ||
// when the values are actually out of range for that type. This could be improved. | ||
|
@@ -351,11 +360,18 @@ where | |
&mut grmtools_section_span_map, | ||
&mut grmtools_section_lex_flags, | ||
)?; | ||
if i == self.src.len() { | ||
return Err(self.mk_error(LexErrorKind::PrematureEnd, i)); | ||
if let Some(j) = self.lookahead_is(",", i) { | ||
i = self.parse_ws(j)?; | ||
continue; | ||
} else { | ||
break; | ||
} | ||
} | ||
i = self.lookahead_is("}", i).unwrap(); | ||
if let Some(j) = self.lookahead_is("}", i) { | ||
i = j | ||
} else { | ||
return Err(self.mk_error(LexErrorKind::PrematureEnd, i)); | ||
} | ||
i = self.parse_ws(i)?; | ||
} | ||
grmtools_section_lex_flags.merge_from(&self.force_lex_flags); | ||
|
@@ -864,7 +880,9 @@ mod test { | |
.expect_err("Parsed ok while expecting error"); | ||
assert_eq!(errs.len(), 1); | ||
let e = &errs[0]; | ||
assert!(e.kind.is_same_kind(&kind)); | ||
if !e.kind.is_same_kind(&kind) { | ||
panic!("expected {:?}.is_same_kind({:?})", &e.kind, &kind); | ||
} | ||
assert_eq!( | ||
e.spans() | ||
.iter() | ||
|
@@ -1864,7 +1882,7 @@ b "A" | |
fn test_grmtools_section_fails() { | ||
let src = r#" | ||
%grmtools { | ||
!unicode | ||
!unicode, | ||
unicode | ||
} | ||
%% | ||
|
@@ -1879,8 +1897,8 @@ b "A" | |
|
||
let src = r#" | ||
%grmtools { | ||
size_limit 5 | ||
size_limit 6 | ||
size_limit: 5, | ||
size_limit: 6, | ||
} | ||
%% | ||
. "dot"; | ||
|
@@ -1894,7 +1912,7 @@ b "A" | |
|
||
let src = r#" | ||
%grmtools { | ||
!size_limit 5 | ||
!size_limit: 5, | ||
} | ||
%% | ||
. "dot" | ||
|
@@ -1906,6 +1924,22 @@ b "A" | |
3, | ||
3, | ||
); | ||
// The following is missing comma separators for more than 2 elements | ||
// This is to avoid parsing it as "key value" number of elements. | ||
// However we actually error after the first element since the parser | ||
// knows "case_insensitive" is a flag with no arguments. | ||
let src = r#" | ||
%grmtools {unicode, case_insensitive posix_escapes allow_comments} | ||
%% | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment indicates a difference between the the I suppose we should consider using So it'd be something like:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess another option would be I don't think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried |
||
. "dot" | ||
\n+ ; | ||
"#; | ||
LRNonStreamingLexerDef::<DefaultLexerTypes<u8>>::from_str(src).expect_error_at_line_col( | ||
src, | ||
LexErrorKind::PrematureEnd, | ||
2, | ||
38, | ||
); | ||
} | ||
|
||
#[test] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -79,10 +79,10 @@ pub(crate) fn run_test_path<P: AsRef<Path>>(path: P) -> Result<(), Box<dyn std:: | |
// Create grammar files | ||
let base = path.file_stem().unwrap().to_str().unwrap(); | ||
let mut pg = PathBuf::from(&out_dir); | ||
pg.push(format!("{}.y.rs", base)); | ||
pg.push(format!("{}.test.y", base)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had believed that this In which case I don't think it's necessary we emit Perhaps best to do that and an audit in a follow up. Or should I revert this part of the change, and change the tests to glob for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Good idea! |
||
fs::write(&pg, grm).unwrap(); | ||
let mut pl = PathBuf::from(&out_dir); | ||
pl.push(format!("{}.l.rs", base)); | ||
pl.push(format!("{}.test.l", base)); | ||
fs::write(&pl, lex).unwrap(); | ||
|
||
// Build parser and lexer | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This highlights another interesting thing, and potential place where we might want to parse
the grmtools section multiple times. E.g. recognizing
yacckind
incfgrammar
, butrecoverer
inlrpar
.Presumably that means cfgrammar should ignore unknown values (rather than it's current strict checking).
This is very similar to the "before LexerKind" vs "after LRNonStreamingLexer" thing with lexerkind except across crates.