use std::sync::Arc;
mod origin;
mod rewrite;
mod state;
mod tokenize;
use crate::pratt::{PrattParser, default_pratt_table};
use sim_codec::{DecodeBudget, DecodeLimits};
use sim_kernel::{Expr, LocatedExpr, PrattTable, Result};
use sim_shape::{PrattShape, Shape, ShapeExprParser};
pub use state::ParseCx;
pub use tokenize::{SpannedToken, tokenize_algol_spanned, tokenize_algol_spanned_with_budget};
pub(crate) use sim_codec_pratt::raw_number_tag;
pub fn decode_algol_located(
codec: sim_kernel::CodecId,
source_id: impl Into<String>,
source: &str,
) -> Result<LocatedExpr> {
let mut budget = DecodeBudget::new(DecodeLimits::default());
budget.check_input_bytes(codec, source.len())?;
decode_algol_located_with_budget(codec, source_id, source, &mut budget)
}
pub fn decode_algol_located_with_budget(
codec: sim_kernel::CodecId,
source_id: impl Into<String>,
source: &str,
budget: &mut DecodeBudget,
) -> Result<LocatedExpr> {
let parser = PrattParser::new(default_pratt_table());
let source_id = sim_kernel::SourceId(source_id.into());
let mut tree =
parser.parse_text_tree_with_budget(codec, source_id.0.clone(), source, budget)?;
tree.origin = Some(origin::origin_from_algol_source(codec, source_id, source)?);
Ok(tree.located())
}
pub fn parse_algol_expr_with_table(
cx: &mut sim_kernel::Cx,
table: PrattTable,
source: &str,
) -> Result<Expr> {
let mut budget = DecodeBudget::new(DecodeLimits::default());
budget.check_input_bytes(sim_kernel::CodecId(0), source.len())?;
parse_algol_expr_with_table_and_budget(cx, table, source, &mut budget)
}
pub fn parse_algol_expr_with_table_and_budget(
cx: &mut sim_kernel::Cx,
table: PrattTable,
source: &str,
budget: &mut DecodeBudget,
) -> Result<Expr> {
let mut tree = PrattParser::new(table).parse_text_tree_with_budget(
sim_kernel::CodecId(0),
"<shape>",
source,
budget,
)?;
rewrite::rewrite_number_domains_tree_lossy(cx, &mut tree)?;
Ok(tree.expr)
}
pub struct AlgolShapeParser {
table: PrattTable,
}
impl AlgolShapeParser {
pub fn new(table: PrattTable) -> Self {
Self { table }
}
pub fn table(&self) -> &PrattTable {
&self.table
}
}
impl ShapeExprParser for AlgolShapeParser {
fn label(&self) -> &str {
"algol-pratt"
}
fn parse_expr(&self, source: &str) -> Result<Expr> {
Ok(PrattParser::new(self.table.clone())
.parse_text_tree(sim_kernel::CodecId(0), "<shape>", source)?
.expr)
}
}
pub fn algol_pratt_shape(table: PrattTable, inner: Arc<dyn Shape>) -> PrattShape {
PrattShape::new(Arc::new(AlgolShapeParser::new(table)), inner)
}