typing parser
parent
16f04399cd
commit
5635aa4ff2
@ -0,0 +1,4 @@
|
|||||||
|
#[inline]
|
||||||
|
pub fn parse_int(s: &str, radix: u32) -> i64 {
|
||||||
|
i64::from_str_radix(&s[2..].replace('_', ""), radix).unwrap()
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
use pest::iterators::Pair;
|
||||||
|
use crate::parser::Parser;
|
||||||
|
use crate::parser::Rule;
|
||||||
|
use crate::error::{CozoError, Result};
|
||||||
|
use crate::parser::number::parse_int;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn parse_raw_string(pair: Pair<Rule>) -> Result<String> {
|
||||||
|
Ok(pair.into_inner().into_iter().next().unwrap().as_str().to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn parse_quoted_string(pair: Pair<Rule>) -> Result<String> {
|
||||||
|
let pairs = pair.into_inner().next().unwrap().into_inner();
|
||||||
|
let mut ret = String::with_capacity(pairs.as_str().len());
|
||||||
|
for pair in pairs {
|
||||||
|
let s = pair.as_str();
|
||||||
|
match s {
|
||||||
|
r#"\""# => ret.push('"'),
|
||||||
|
r"\\" => ret.push('\\'),
|
||||||
|
r"\/" => ret.push('/'),
|
||||||
|
r"\b" => ret.push('\x08'),
|
||||||
|
r"\f" => ret.push('\x0c'),
|
||||||
|
r"\n" => ret.push('\n'),
|
||||||
|
r"\r" => ret.push('\r'),
|
||||||
|
r"\t" => ret.push('\t'),
|
||||||
|
s if s.starts_with(r"\u") => {
|
||||||
|
let code = parse_int(s, 16) as u32;
|
||||||
|
let ch = char::from_u32(code).ok_or(CozoError::InvalidUtfCode)?;
|
||||||
|
ret.push(ch);
|
||||||
|
}
|
||||||
|
s if s.starts_with('\\') => return Err(CozoError::InvalidEscapeSequence),
|
||||||
|
s => ret.push_str(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn parse_s_quoted_string(pair: Pair<Rule>) -> Result<String> {
|
||||||
|
let pairs = pair.into_inner().next().unwrap().into_inner();
|
||||||
|
let mut ret = String::with_capacity(pairs.as_str().len());
|
||||||
|
for pair in pairs {
|
||||||
|
let s = pair.as_str();
|
||||||
|
match s {
|
||||||
|
r#"\'"# => ret.push('\''),
|
||||||
|
r"\\" => ret.push('\\'),
|
||||||
|
r"\/" => ret.push('/'),
|
||||||
|
r"\b" => ret.push('\x08'),
|
||||||
|
r"\f" => ret.push('\x0c'),
|
||||||
|
r"\n" => ret.push('\n'),
|
||||||
|
r"\r" => ret.push('\r'),
|
||||||
|
r"\t" => ret.push('\t'),
|
||||||
|
s if s.starts_with(r"\u") => {
|
||||||
|
let code = parse_int(s, 16) as u32;
|
||||||
|
let ch = char::from_u32(code).ok_or(CozoError::InvalidUtfCode)?;
|
||||||
|
ret.push(ch);
|
||||||
|
}
|
||||||
|
s if s.starts_with('\\') => return Err(CozoError::InvalidEscapeSequence),
|
||||||
|
s => ret.push_str(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn parse_string(pair: Pair<Rule>) -> Result<String> {
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::quoted_string => Ok(parse_quoted_string(pair)?),
|
||||||
|
Rule::s_quoted_string => Ok(parse_s_quoted_string(pair)?),
|
||||||
|
Rule::raw_string => Ok(parse_raw_string(pair)?),
|
||||||
|
Rule::ident => Ok(pair.as_str().to_string()),
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_ident(pair: Pair<Rule>) -> String {
|
||||||
|
pair.as_str().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_name_in_def(pair: Pair<Rule>, forbid_underscore: bool) -> Result<String> {
|
||||||
|
let inner = pair.into_inner().next().unwrap();
|
||||||
|
let name = match inner.as_rule() {
|
||||||
|
Rule::ident => parse_ident(inner),
|
||||||
|
Rule::raw_string | Rule::s_quoted_string | Rule::quoted_string => parse_string(inner)?,
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
if forbid_underscore && name.starts_with('_') {
|
||||||
|
Err(CozoError::ReservedIdent)
|
||||||
|
} else {
|
||||||
|
Ok(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_col_name(pair: Pair<Rule>) -> Result<(String, bool)> {
|
||||||
|
let mut pairs = pair.into_inner();
|
||||||
|
let mut is_key = false;
|
||||||
|
let mut nxt_pair = pairs.next().unwrap();
|
||||||
|
if nxt_pair.as_rule() == Rule::key_marker {
|
||||||
|
is_key = true;
|
||||||
|
nxt_pair = pairs.next().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((build_name_in_def(nxt_pair, true)?, is_key))
|
||||||
|
}
|
Loading…
Reference in New Issue