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