mod atoms;
mod body;
mod primary;
pub(super) use crate::parser::syntax_kind::SyntaxKind;
pub use self::atoms::*;
pub use self::body::*;
pub use self::primary::*;
pub trait ExpressionParser {
fn current_kind(&self) -> SyntaxKind;
fn at(&self, kind: SyntaxKind) -> bool;
fn at_any(&self, kinds: &[SyntaxKind]) -> bool;
fn at_name_token(&self) -> bool;
fn get_pos(&self) -> usize;
fn peek_kind(&self, n: usize) -> SyntaxKind;
fn bump(&mut self);
fn bump_any(&mut self);
fn expect(&mut self, kind: SyntaxKind);
fn skip_trivia(&mut self);
fn start_node(&mut self, kind: SyntaxKind);
fn finish_node(&mut self);
fn parse_qualified_name(&mut self);
fn parse_argument(&mut self);
}
pub fn parse_expression<P: ExpressionParser>(p: &mut P) -> bool {
let start_pos = p.get_pos();
parse_conditional_expression(p);
p.get_pos() > start_pos
}
fn parse_ternary_conditional<P: ExpressionParser>(p: &mut P) {
p.bump(); p.skip_trivia();
parse_expression(p);
p.skip_trivia();
if p.at(SyntaxKind::ELSE_KW) {
p.bump();
p.skip_trivia();
parse_expression(p);
}
}
fn parse_keyword_conditional<P: ExpressionParser>(p: &mut P) {
p.bump(); p.skip_trivia();
parse_expression(p);
p.skip_trivia();
if p.at(SyntaxKind::ELSE_KW) {
p.bump();
p.skip_trivia();
parse_expression(p);
}
}
pub fn parse_conditional_expression<P: ExpressionParser>(p: &mut P) {
p.start_node(SyntaxKind::EXPRESSION);
if p.at(SyntaxKind::IF_KW) {
p.bump(); p.skip_trivia();
parse_null_coalescing_expression(p); p.skip_trivia();
if p.at(SyntaxKind::QUESTION) {
parse_ternary_conditional(p);
} else if p.at(SyntaxKind::THEN_KW) {
parse_keyword_conditional(p);
}
} else {
parse_null_coalescing_expression(p);
p.skip_trivia();
if p.at(SyntaxKind::QUESTION) && !p.at(SyntaxKind::QUESTION_QUESTION) {
p.bump(); p.skip_trivia();
parse_expression(p); p.skip_trivia();
p.expect(SyntaxKind::COLON);
p.skip_trivia();
parse_expression(p); }
}
p.finish_node();
}
pub fn parse_null_coalescing_expression<P: ExpressionParser>(p: &mut P) {
parse_implies_expression(p);
while p.at(SyntaxKind::QUESTION_QUESTION) {
p.bump();
p.skip_trivia();
parse_implies_expression(p);
}
}
pub fn parse_implies_expression<P: ExpressionParser>(p: &mut P) {
parse_or_expression(p);
while p.at(SyntaxKind::IMPLIES_KW) {
p.bump();
p.skip_trivia();
parse_or_expression(p);
}
}
pub fn parse_or_expression<P: ExpressionParser>(p: &mut P) {
parse_xor_expression(p);
p.skip_trivia();
while p.at(SyntaxKind::PIPE) || p.at(SyntaxKind::OR_KW) {
p.bump();
p.skip_trivia();
parse_xor_expression(p);
p.skip_trivia();
}
}
pub fn parse_xor_expression<P: ExpressionParser>(p: &mut P) {
parse_and_expression(p);
p.skip_trivia();
while p.at(SyntaxKind::XOR_KW) {
p.bump();
p.skip_trivia();
parse_and_expression(p);
p.skip_trivia();
}
}
pub fn parse_and_expression<P: ExpressionParser>(p: &mut P) {
parse_equality_expression(p);
p.skip_trivia();
while p.at(SyntaxKind::AMP) || p.at(SyntaxKind::AND_KW) {
p.bump();
p.skip_trivia();
parse_equality_expression(p);
p.skip_trivia();
}
}
pub fn parse_equality_expression<P: ExpressionParser>(p: &mut P) {
parse_classification_expression(p);
p.skip_trivia();
while p.at_any(&[
SyntaxKind::EQ_EQ,
SyntaxKind::BANG_EQ,
SyntaxKind::EQ_EQ_EQ,
SyntaxKind::BANG_EQ_EQ,
]) {
p.bump();
p.skip_trivia();
parse_classification_expression(p);
p.skip_trivia();
}
}
pub fn parse_classification_expression<P: ExpressionParser>(p: &mut P) {
if p.at_any(&[SyntaxKind::HASTYPE_KW, SyntaxKind::ISTYPE_KW]) {
p.bump();
p.skip_trivia();
p.parse_qualified_name();
return;
}
parse_relational_expression(p);
p.skip_trivia();
if p.at_any(&[
SyntaxKind::HASTYPE_KW,
SyntaxKind::ISTYPE_KW,
SyntaxKind::AS_KW,
SyntaxKind::META_KW,
SyntaxKind::AT,
SyntaxKind::AT_AT,
]) {
p.bump();
p.skip_trivia();
p.parse_qualified_name();
}
}
pub fn parse_relational_expression<P: ExpressionParser>(p: &mut P) {
parse_range_expression(p);
p.skip_trivia();
while p.at_any(&[
SyntaxKind::LT,
SyntaxKind::GT,
SyntaxKind::LT_EQ,
SyntaxKind::GT_EQ,
]) {
p.bump();
p.skip_trivia();
parse_range_expression(p);
p.skip_trivia();
}
}
pub fn parse_range_expression<P: ExpressionParser>(p: &mut P) {
parse_additive_expression(p);
p.skip_trivia();
if p.at(SyntaxKind::DOT_DOT) {
p.bump();
p.skip_trivia();
parse_additive_expression(p);
}
}
pub fn parse_additive_expression<P: ExpressionParser>(p: &mut P) {
parse_multiplicative_expression(p);
while p.at(SyntaxKind::PLUS) || p.at(SyntaxKind::MINUS) {
p.bump();
p.skip_trivia();
parse_multiplicative_expression(p);
}
}
pub fn parse_multiplicative_expression<P: ExpressionParser>(p: &mut P) {
parse_exponentiation_expression(p);
while p.at_any(&[SyntaxKind::STAR, SyntaxKind::SLASH, SyntaxKind::PERCENT]) {
p.bump();
p.skip_trivia();
parse_exponentiation_expression(p);
}
}
pub fn parse_exponentiation_expression<P: ExpressionParser>(p: &mut P) {
parse_unary_expression(p);
p.skip_trivia();
if p.at(SyntaxKind::STAR_STAR) || p.at(SyntaxKind::CARET) {
p.bump();
p.skip_trivia();
parse_exponentiation_expression(p);
}
}
pub fn parse_unary_expression<P: ExpressionParser>(p: &mut P) {
if p.at_any(&[
SyntaxKind::PLUS,
SyntaxKind::MINUS,
SyntaxKind::TILDE,
SyntaxKind::NOT_KW,
]) {
p.bump();
p.skip_trivia();
}
parse_extent_expression(p);
}
pub fn parse_extent_expression<P: ExpressionParser>(p: &mut P) {
if p.at(SyntaxKind::ALL_KW) {
p.bump();
p.skip_trivia();
}
parse_primary_expression(p);
}