-
Notifications
You must be signed in to change notification settings - Fork 13
Add newline to the parsing grammar to resolve some bugs #56
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
base: master
Are you sure you want to change the base?
Conversation
Was replaced with broken_intra_doc_links.
Fix skip_whitespace test and add respect_newlines test.
Removed part of the test that was simply invalid.
Tweaked it to return the expected newline character.
8d7dfa8
to
c11ad15
Compare
Both fail, and are the basis for a new bug report.
c11ad15
to
2107449
Compare
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.
Thanks for making this PR @jmbeck15! I think adding newlines as an explicit token in the language totally makes sense.
Overall I'm pretty happy with the PR, but there were a couple small questions I'd like to get your thoughts on.
fn tokenize_newline(&mut self) -> Option<Token<'input>> { | ||
let start = self.current_position; | ||
let line = self.current_line; | ||
let value = "\n"; | ||
self.current_position += 1; | ||
self.current_line += 1; | ||
Some(Token { | ||
kind: TokenType::Newline, | ||
value, | ||
span: Span { | ||
start, | ||
line, | ||
end: start + 1, | ||
}, | ||
}) | ||
} |
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.
If the only way this function can be called is when we're looking at a \n
character, would it be enough to add something like debug_assert!(self.rest().starts_with("\n"))
and return a Token<'input>
?
Otherwise, we should actually check for the newline character and return None
if it isn't found.
Either way, I think we should try to use the newline characters from the original stream instead of writing let value = "\n"
.
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.
I think what you're getting at is "this code has a weird smell", and I think you're right. 😁 But I'm honestly not sure how to construct this better. If we don't explicitly set value = "\n"
, we'd have to chomp()
or somehow otherwise pull the newline from the string, which is a computational expense that seems superfluous.
As for your suggestion
would it be enough to add something like
debug_assert!(self.rest().starts_with("\n"))
and return aToken<'input>
I don't think I understand. The debug_assert
is something I could add; seems reasonable. But how would you return the Token<'input>
?
@@ -371,4 +404,44 @@ mod tests { | |||
|
|||
assert_eq!(got.value, "+3.14"); | |||
} | |||
|
|||
#[test] | |||
fn two_multi() { |
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.
It would probably be more readable if we rewrite the test to be something like this:
let expected = vec![
("G", 0),
("0", 0),
("X", 0),
...
];
let actual: Vec<_> = Lexer::new("...")
.map(|tok| (tok.value, tok.span.line))
.collect();
assert_eq!(actual, expected);
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.
For long g-code example tests, that's probably the way to go. Maybe we could create some helper methods that make testing easier. We're really missing these long-form g-code verification tests, so I took this one from the pull request @dr0ps made.
How about we keep this test as is for now, and rework these kinds of tests in the future?
Co-authored-by: Michael Bryan <michaelfbryan@gmail.com>
Co-authored-by: Michael Bryan <michaelfbryan@gmail.com>
@Michael-F-Bryan I pushed two more commits, one of which fixes #55. I was going to wait until after this pull request was merged to fix #55, but it turns out very much related to the newline handling. If you prefer these fixes in separate pull requests, just let me know. |
Howdy! In case anyone is still out there, I tried using this library and ran into a bug. The library panicked on the gcode generated by DrawingBotV3-Free. Anyways, I am interested to know if this change would fix it. I'm hoping this message will motivate someone to resolve this merge request. |
@jpursell if you send me some minimal example code that panics the library, I'll check it out. I'm curious. |
Summary
By adding newline (
\n
) to the grammar, this pull request will:It may be easier to review by commit than in bulk.
Description
Newlines are special for GCode; they represent the end of the current command and the start of a new one. This commit makes newlines a first-class token, and parses with them under consideration.
How I tested
I added some tests, un-ignored or fixed other tests, and executed
cargo test
.I also ran a bunch of gcode files through the parser as a sanity check. In retrospect, I should have created tests from them, so I may go back and do that if I need to make further changes.