From 0829b16fc9a101d743dd14e79fe396fd81e493fe Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Wed, 31 Jan 2024 02:15:50 -0800 Subject: [PATCH] Parser representations --- src/annotated.rs | 4 ++++ src/parser.rs | 5 ++++- src/primitives.rs | 18 ++++++++++++++---- src/representation.rs | 15 +++++++++++---- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/annotated.rs b/src/annotated.rs index bff85d3..cbcf189 100644 --- a/src/annotated.rs +++ b/src/annotated.rs @@ -23,6 +23,10 @@ where fn name(&self) -> Option { self.name.clone() } + + fn representation(&self) -> Option { + self.repr.clone() + } } impl AnnotatedParser diff --git a/src/parser.rs b/src/parser.rs index a3a957f..27fb9f7 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,4 +1,4 @@ -use crate::{annotated::AnnotatedParser, map, seq2, surrounded_by}; +use crate::{annotated::AnnotatedParser, map, representation::Representation, seq2, surrounded_by}; pub type ParseResult = Result<(O, I), (E, I)>; @@ -7,6 +7,9 @@ pub trait Parser { fn name(&self) -> Option { None } + fn representation(&self) -> Option { + None + } } impl Parser for F diff --git a/src/primitives.rs b/src/primitives.rs index 9989818..c3c92ca 100644 --- a/src/primitives.rs +++ b/src/primitives.rs @@ -1,18 +1,25 @@ -use crate::{representation::Representation, ParseResult, Parser, ParserExtension}; +use crate::{ + representation::{Representation, EBNF}, + ParseResult, Parser, ParserExtension, +}; pub fn literal<'a>(expected: &'static str) -> impl Parser<&'a str, &'a str, ()> { let p = move |input: &'a str| match input.get(0..expected.len()) { Some(next) if next == expected => Ok((next, &input[expected.len()..])), _ => Err(((), input)), }; - p.to_anno().with_repr(Representation::new()) + let production = EBNF::StringTerminal(expected.into()); + p.to_anno() + .with_repr(Representation::new().with_production(production)) } pub fn literal_char<'a>(expected: char) -> impl Parser<&'a str, char, ()> { - move |input: &'a str| match input.chars().next() { + (move |input: &'a str| match input.chars().next() { Some(ch) if ch == expected => Ok((expected, &input[ch.len_utf8()..])), _ => Err(((), input)), - } + }) + .to_anno() + .with_repr(Representation::new().with_production(EBNF::CharTerminal(expected))) } pub fn one_of<'a>(items: &'static str) -> impl Parser<&'a str, char, ()> { @@ -64,5 +71,8 @@ mod tests { fn literals() { let parser = literal_char('f'); assert_eq!(Ok(('f', "unky")), parser.parse("funky")); + + let repr = parser.representation().unwrap(); + assert!(matches!(repr.production(), EBNF::CharTerminal('f'))); } } diff --git a/src/representation.rs b/src/representation.rs index 59a7f87..f507817 100644 --- a/src/representation.rs +++ b/src/representation.rs @@ -2,7 +2,7 @@ use std::fmt; use crate::util::intersperse_option; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Representation { production_output: EBNF, } @@ -12,18 +12,25 @@ impl Representation { self.production_output.to_string() } + pub fn production(&self) -> EBNF { + self.production_output.clone() + } + pub fn new() -> Self { Self { production_output: EBNF::None, } } - pub fn with_production(production_output: EBNF) -> Self { - Self { production_output } + pub fn with_production(self, production_output: EBNF) -> Self { + Self { + production_output, + ..self + } } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum EBNF { None, Nonterminal(String),