docs: explain some of the string parsing
This commit is contained in:
parent
f22011e59e
commit
cc88a4240a
1 changed files with 23 additions and 9 deletions
|
|
@ -25,16 +25,30 @@ enum ParsingState {
|
||||||
impl FromStr for Nodes {
|
impl FromStr for Nodes {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
/// A superset of `char::is_numeric`
|
||||||
|
/// that includes other characters parseable into numbers,
|
||||||
|
/// such as `.` (for decimal) and `e` for scientific notation.
|
||||||
|
fn is_number_char(c: char) -> bool {
|
||||||
|
match c {
|
||||||
|
'.' | 'e' => true,
|
||||||
|
c => c.is_numeric(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A function to check if the given `char` should be used by the parser.
|
||||||
|
///
|
||||||
|
/// We ignore whitespace since it has no semantic significance in typst aside from variables,
|
||||||
|
/// (which are not implemented)
|
||||||
|
/// and `&` because it is only used for visual alignment.
|
||||||
|
///
|
||||||
|
/// Newlines are also ignored because they're likely accidental; like in the case of `echo 1+1 | tylc`.
|
||||||
|
fn is_not_ignored_char(c: &char) -> bool {
|
||||||
|
!matches!(c, ' ' | '&' | '\n')
|
||||||
|
}
|
||||||
|
|
||||||
let mut nodes = Vec::new();
|
let mut nodes = Vec::new();
|
||||||
let mut state = ParsingState::default();
|
let mut state = ParsingState::default();
|
||||||
|
|
||||||
let is_ignored_char = |c: &char| !matches!(c, ' ' | '&' | '\n');
|
let filtered_string: String = s.chars().filter(is_not_ignored_char).collect();
|
||||||
let is_numeric_char = |c: char| match c {
|
|
||||||
'.' | 'e' => true,
|
|
||||||
c => c.is_numeric(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let filtered_string: String = s.chars().filter(is_ignored_char).collect();
|
|
||||||
|
|
||||||
for (i, c) in filtered_string.char_indices() {
|
for (i, c) in filtered_string.char_indices() {
|
||||||
match state {
|
match state {
|
||||||
|
|
@ -51,7 +65,7 @@ impl FromStr for Nodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ParsingState::ReadingNumber(start_index) => {
|
ParsingState::ReadingNumber(start_index) => {
|
||||||
if !is_numeric_char(c) {
|
if !is_number_char(c) {
|
||||||
nodes.push(Node::Number(
|
nodes.push(Node::Number(
|
||||||
Float::parse(&filtered_string[start_index..i])
|
Float::parse(&filtered_string[start_index..i])
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
|
|
@ -69,7 +83,7 @@ impl FromStr for Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
if state == ParsingState::Start {
|
if state == ParsingState::Start {
|
||||||
if is_numeric_char(c) {
|
if is_number_char(c) {
|
||||||
state = ParsingState::ReadingNumber(i);
|
state = ParsingState::ReadingNumber(i);
|
||||||
} else if c.is_alphabetic() {
|
} else if c.is_alphabetic() {
|
||||||
state = ParsingState::ReadingFunctionName(i);
|
state = ParsingState::ReadingFunctionName(i);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue