parsing is *doom music start plaing* inducing
This commit is contained in:
parent
ba8f867bd9
commit
f223e2401e
@ -11,8 +11,7 @@ element_fields -> (_ element_field (__linebreak__ element_field):*):? __linebrea
|
||||
|
||||
element_field ->
|
||||
| element
|
||||
| Id
|
||||
| Class
|
||||
| specifier_chain
|
||||
| element_property
|
||||
| value
|
||||
|
||||
@ -20,22 +19,20 @@ element_property -> Name _ ("=" | ":") _ value
|
||||
|
||||
single_line_fields ->
|
||||
(first_single_line_field
|
||||
(__singleline__ single_line_field):*):? _singleline_
|
||||
(__sl__ single_line_field):*):? _sl_
|
||||
|
||||
first_single_line_field ->
|
||||
| Id
|
||||
| Class
|
||||
| __singleline__ single_line_element_property
|
||||
| __singleline__ single_line_value
|
||||
| specifier_chain
|
||||
| __sl__ single_line_element_property
|
||||
| __sl__ single_line_value
|
||||
|
||||
single_line_field ->
|
||||
| Id
|
||||
| Class
|
||||
| specifier_chain
|
||||
| single_line_element_property
|
||||
| single_line_value
|
||||
|
||||
single_line_element_property ->
|
||||
Name _singleline_ ("=" | ":") _singleline_ value
|
||||
Name _sl_ ("=" | ":") _sl_ value
|
||||
|
||||
single_line_value ->
|
||||
| array
|
||||
@ -45,6 +42,12 @@ single_line_value ->
|
||||
| bool
|
||||
| Null
|
||||
|
||||
specifier_chain -> specifier:+
|
||||
|
||||
specifier ->
|
||||
| Id
|
||||
| Class
|
||||
|
||||
value ->
|
||||
| object
|
||||
| array
|
||||
@ -67,28 +70,27 @@ array_values -> (_ value (_ "," _ value):* _ ",":?):? _
|
||||
|
||||
bool -> True | False
|
||||
|
||||
__singleline__ -> mandatory_same_line_whitespace
|
||||
_singleline_ -> optional_same_line_whitespace
|
||||
__linebreak__ -> mandatory_linebreak
|
||||
__ -> mandatory_whitespace
|
||||
__sl__ -> mandatory_single_line_whitespace
|
||||
_sl_ -> optional_single_line_whitespace
|
||||
__ml__ -> mandatory_whitespace
|
||||
_ -> optional_whitespace
|
||||
|
||||
mandatory_same_line_whitespace -> single_line_whitespace:+
|
||||
optional_same_line_whitespace -> single_line_whitespace:*
|
||||
|
||||
mandatory_linebreak ->
|
||||
single_line_whitespace:*
|
||||
line_breaker
|
||||
whitespace_and_line_break:*
|
||||
|
||||
single_line_whitespace -> SingleLineWhitespace | MultiLineComment
|
||||
|
||||
line_breaker -> MultiLineComment | MultiLineWhitespace | ";"
|
||||
|
||||
whitespace_and_line_break -> singular_whitespace | ";"
|
||||
|
||||
optional_whitespace -> singular_whitespace:*
|
||||
mandatory_single_line_whitespace -> single_line_whitespace:+
|
||||
optional_single_line_whitespace -> single_line_whitespace:*
|
||||
|
||||
single_line_whitespace -> SingleLineWhitespace | MultiLineComment
|
||||
|
||||
optional_whitespace -> singular_whitespace:*
|
||||
mandatory_whitespace -> singular_whitespace:+
|
||||
|
||||
singular_whitespace ->
|
||||
|
@ -62,30 +62,49 @@ impl Parser {
|
||||
Some(Token::Id(value)) => {
|
||||
fields.push(ElementField::Id(value.clone()));
|
||||
self.step();
|
||||
todo!()
|
||||
}
|
||||
Some(Token::Class(value)) => {
|
||||
fields.push(ElementField::Class(value.clone()));
|
||||
self.step();
|
||||
todo!()
|
||||
}
|
||||
_ => todo!(),
|
||||
Some(_) => todo!(),
|
||||
_ => Ok(fields),
|
||||
}
|
||||
Ok(fields)
|
||||
}
|
||||
|
||||
fn parse_value(&mut self) -> Result<Node, ParserError> {
|
||||
match self.current() {
|
||||
Some(Token::LBrace(_)) => self.parse_object(),
|
||||
Some(Token::LBracket(_)) => self.parse_object(),
|
||||
Some(Token::Int(value)) => Ok(Node::Int(
|
||||
value.parse().map_err(|_| "malformed int".to_string())?,
|
||||
)),
|
||||
Some(Token::Float(value)) => Ok(Node::Int(
|
||||
value.parse().map_err(|_| "malformed float".to_string())?,
|
||||
)),
|
||||
Some(Token::String(value)) => Ok(Node::String(value[1..value.len() - 1].to_string())),
|
||||
Some(Token::False(_)) => Ok(Node::Bool(false)),
|
||||
Some(Token::True(_)) => Ok(Node::Bool(false)),
|
||||
Some(Token::Null(_)) => Ok(Node::Null),
|
||||
Some(Token::Int(value)) => {
|
||||
let value = value.parse().map_err(|_| "malformed int".to_string())?;
|
||||
self.step();
|
||||
Ok(Node::Int(value))
|
||||
}
|
||||
Some(Token::Float(value)) => {
|
||||
let value = value.parse().map_err(|_| "malformed float".to_string())?;
|
||||
self.step();
|
||||
Ok(Node::Float(value))
|
||||
}
|
||||
Some(Token::String(value)) => {
|
||||
let value = value[1..value.len() - 1].to_string();
|
||||
self.step();
|
||||
Ok(Node::String(value))
|
||||
}
|
||||
Some(Token::False(_)) => {
|
||||
self.step();
|
||||
Ok(Node::Bool(false))
|
||||
}
|
||||
Some(Token::True(_)) => {
|
||||
self.step();
|
||||
Ok(Node::Bool(false))
|
||||
}
|
||||
Some(Token::Null(_)) => {
|
||||
self.step();
|
||||
Ok(Node::Null)
|
||||
}
|
||||
Some(_) => Err("unexpected token, expected value".to_owned()),
|
||||
None => Err("expected value".to_owned()),
|
||||
}
|
||||
@ -93,6 +112,8 @@ impl Parser {
|
||||
|
||||
fn parse_object(&mut self) -> Result<Node, ParserError> {
|
||||
self.step();
|
||||
// object_properties -> (_ (...)):? _ <=> object_properties -> _ | _ (...) _
|
||||
self.parse_optional_whitespace()?;
|
||||
let mut values = HashMap::<String, Box<Node>>::new();
|
||||
match self.current() {
|
||||
Some(Token::RBrace(_)) => {
|
||||
@ -106,11 +127,13 @@ impl Parser {
|
||||
_ => panic!("checked by previous predicate"),
|
||||
};
|
||||
self.step();
|
||||
self.parse_optional_whitespace()?;
|
||||
match self.current() {
|
||||
Some(Token::Equal(_) | Token::Colon(_)) => {}
|
||||
_ => return Err("expected ':' or '='".to_string()),
|
||||
}
|
||||
self.step();
|
||||
self.parse_optional_whitespace()?;
|
||||
values.insert(key, Box::new(self.parse_value()?));
|
||||
self.parse_object_tail(values)
|
||||
}
|
||||
@ -123,6 +146,7 @@ impl Parser {
|
||||
mut values: HashMap<String, Box<Node>>,
|
||||
) -> Result<Node, String> {
|
||||
loop {
|
||||
self.parse_optional_whitespace()?;
|
||||
match self.current() {
|
||||
Some(Token::RBrace(_)) => {
|
||||
self.step();
|
||||
@ -130,6 +154,7 @@ impl Parser {
|
||||
}
|
||||
Some(Token::Comma(_)) => {
|
||||
self.step();
|
||||
self.parse_optional_whitespace()?;
|
||||
match self.current() {
|
||||
Some(Token::RBrace(_)) => {
|
||||
self.step();
|
||||
@ -142,13 +167,15 @@ impl Parser {
|
||||
_ => panic!("unterminated object, checked by previous predicate"),
|
||||
};
|
||||
self.step();
|
||||
self.parse_optional_whitespace()?;
|
||||
match self.current() {
|
||||
Some(Token::Equal(_) | Token::Colon(_)) => {}
|
||||
_ => return Err("expected ':' or '='".to_string()),
|
||||
}
|
||||
self.step();
|
||||
self.parse_optional_whitespace()?;
|
||||
values.insert(key, Box::new(self.parse_value()?));
|
||||
todo!()
|
||||
self.parse_optional_whitespace()?;
|
||||
}
|
||||
_ => {
|
||||
break Err(
|
||||
@ -164,6 +191,7 @@ impl Parser {
|
||||
|
||||
fn parse_array(&mut self) -> Result<Node, ParserError> {
|
||||
self.step();
|
||||
self.parse_optional_whitespace()?;
|
||||
let mut values = Vec::<Node>::new();
|
||||
match self.current() {
|
||||
Some(Token::RBracket(_)) => {
|
||||
@ -172,12 +200,112 @@ impl Parser {
|
||||
}
|
||||
Some(_) => {
|
||||
values.push(self.parse_value()?);
|
||||
todo!()
|
||||
loop {
|
||||
match self.current() {
|
||||
Some(Token::RBracket(_)) => {
|
||||
self.step();
|
||||
break Ok(Node::Array(values));
|
||||
}
|
||||
Some(Token::Comma(_)) => {
|
||||
self.step();
|
||||
self.parse_optional_whitespace()?;
|
||||
match self.current() {
|
||||
Some(Token::RBracket(_)) => {
|
||||
self.step();
|
||||
self.parse_optional_whitespace()?;
|
||||
break Ok(Node::Array(values));
|
||||
}
|
||||
_ => {
|
||||
self.step();
|
||||
self.parse_optional_whitespace()?;
|
||||
values.push(self.parse_value()?)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => break Err("unterminated array, expected Value or ']'".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => Err("unterminated array, expected Value or ']'".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_mandatory_linebreak(&mut self) -> Result<(), ParserError> {
|
||||
self.parse_single_line_optional_whitespace()?;
|
||||
match self.current() {
|
||||
Some(Token::MlWhitespace(_) | Token::MlComment(_) | Token::SemiColon(_)) => {
|
||||
self.step();
|
||||
loop {
|
||||
match self.current() {
|
||||
Some(
|
||||
Token::MlWhitespace(_)
|
||||
| Token::SlWhitespace(_)
|
||||
| Token::MlComment(_)
|
||||
| Token::SlComment(_)
|
||||
| Token::SemiColon(_),
|
||||
) => {
|
||||
self.step();
|
||||
}
|
||||
_ => break Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => Err("expected linebreak".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_single_line_mandatory_whitespace(&mut self) -> Result<(), ParserError> {
|
||||
match self.current() {
|
||||
Some(Token::SlWhitespace(_) | Token::SlComment(_)) => {
|
||||
self.step();
|
||||
self.parse_single_line_optional_whitespace()
|
||||
}
|
||||
_ => Err("expected whitespace".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_single_line_optional_whitespace(&mut self) -> Result<(), ParserError> {
|
||||
loop {
|
||||
match self.current() {
|
||||
Some(Token::SlWhitespace(_) | Token::SlComment(_)) => {
|
||||
self.step();
|
||||
}
|
||||
_ => break Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_mandatory_whitespace(&mut self) -> Result<(), ParserError> {
|
||||
match self.current() {
|
||||
Some(
|
||||
Token::MlWhitespace(_)
|
||||
| Token::SlWhitespace(_)
|
||||
| Token::MlComment(_)
|
||||
| Token::SlComment(_),
|
||||
) => {
|
||||
self.step();
|
||||
self.parse_optional_whitespace()
|
||||
}
|
||||
_ => Err("expected whitespace".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_optional_whitespace(&mut self) -> Result<(), ParserError> {
|
||||
loop {
|
||||
match self.current() {
|
||||
Some(
|
||||
Token::MlWhitespace(_)
|
||||
| Token::SlWhitespace(_)
|
||||
| Token::MlComment(_)
|
||||
| Token::SlComment(_),
|
||||
) => {
|
||||
self.step();
|
||||
}
|
||||
_ => break Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn step(&mut self) {
|
||||
self.index += 1
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user