use crate::parse::tokenize_algol_spanned_with_budget;
use sim_codec::{DecodeBudget, DecodeLimits};
use sim_codec_pratt::{PrattCodecParser, PrattTokenSource, SpannedPrattToken};
use sim_kernel::{CodecId, LocatedExprTree, PrattTable, Result};
#[derive(Clone, Copy, Debug, Default)]
pub struct AlgolTokenSource;
impl PrattTokenSource for AlgolTokenSource {
fn tokenize_pratt(
&self,
_codec: CodecId,
source: &str,
budget: &mut DecodeBudget,
) -> Result<Vec<SpannedPrattToken>> {
tokenize_algol_spanned_with_budget(source, budget).map(|tokens| {
tokens
.into_iter()
.map(|token| {
SpannedPrattToken::with_leading_trivia(
token.token,
token.start,
token.end,
token.leading_trivia,
)
})
.collect()
})
}
}
pub struct PrattParser {
inner: PrattCodecParser<AlgolTokenSource>,
}
impl PrattParser {
pub fn new(operators: PrattTable) -> Self {
Self {
inner: PrattCodecParser::new(operators, AlgolTokenSource).with_surface_name("algol"),
}
}
pub fn operators(&self) -> &PrattTable {
self.inner.operators()
}
pub fn parse_text_tree(
&self,
codec: CodecId,
source_id: impl Into<String>,
source: &str,
) -> Result<LocatedExprTree> {
let mut budget = DecodeBudget::new(DecodeLimits::default());
self.parse_text_tree_with_budget(codec, source_id, source, &mut budget)
}
pub fn parse_text_tree_with_budget(
&self,
codec: CodecId,
source_id: impl Into<String>,
source: &str,
budget: &mut DecodeBudget,
) -> Result<LocatedExprTree> {
self.inner.parse_tree_with_source_and_budget(
codec,
sim_kernel::SourceId(source_id.into()),
source,
budget,
)
}
}