starting ebnf representation
This commit is contained in:
parent
4e813a7efd
commit
698e05081a
@ -7,6 +7,7 @@ mod parser;
|
|||||||
mod primitives;
|
mod primitives;
|
||||||
mod representation;
|
mod representation;
|
||||||
mod sequence;
|
mod sequence;
|
||||||
|
mod util;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
@ -1,12 +1,66 @@
|
|||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use crate::util::intersperse_option;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Representation {}
|
pub struct Representation {
|
||||||
|
production_output: EBNF,
|
||||||
|
}
|
||||||
|
|
||||||
impl Representation {
|
impl Representation {
|
||||||
pub fn show(&self) {
|
pub fn show(&self) -> String {
|
||||||
println!("Not done");
|
self.production_output.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {}
|
Self {
|
||||||
|
production_output: EBNF::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_production(production_output: EBNF) -> Self {
|
||||||
|
Self { production_output }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum EBNF {
|
||||||
|
None,
|
||||||
|
CharTerminal(char),
|
||||||
|
Alternation(Vec<EBNF>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for EBNF {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
EBNF::None => write!(f, "none"),
|
||||||
|
EBNF::CharTerminal(ch) => write!(f, "'{ch}'"),
|
||||||
|
EBNF::Alternation(items) => {
|
||||||
|
for item in intersperse_option(items.iter()) {
|
||||||
|
match item {
|
||||||
|
None => write!(f, " | ")?,
|
||||||
|
Some(item) => write!(f, "{item}")?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write!(f, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ebnf_print() {
|
||||||
|
let example = EBNF::Alternation(vec![
|
||||||
|
EBNF::CharTerminal('f'),
|
||||||
|
EBNF::CharTerminal('a'),
|
||||||
|
EBNF::CharTerminal('k'),
|
||||||
|
EBNF::CharTerminal('e'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert_eq!(example.to_string(), "'f' | 'a' | 'k' | 'e'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
46
src/util.rs
Normal file
46
src/util.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
use std::iter::Peekable;
|
||||||
|
|
||||||
|
pub(crate) fn intersperse_option<I: Iterator>(iterator: I) -> impl Iterator<Item = Option<I::Item>>
|
||||||
|
where
|
||||||
|
I::Item: Clone,
|
||||||
|
{
|
||||||
|
intersperse(iterator.map(Some), None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn intersperse<I: Iterator>(iterator: I, separator: I::Item) -> Intersperse<I>
|
||||||
|
where
|
||||||
|
I::Item: Clone,
|
||||||
|
{
|
||||||
|
Intersperse {
|
||||||
|
inner: iterator.peekable(),
|
||||||
|
separator,
|
||||||
|
needs_sep: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Intersperse<I>
|
||||||
|
where
|
||||||
|
I: Iterator,
|
||||||
|
{
|
||||||
|
inner: Peekable<I>,
|
||||||
|
separator: I::Item,
|
||||||
|
needs_sep: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> Iterator for Intersperse<I>
|
||||||
|
where
|
||||||
|
I: Iterator,
|
||||||
|
I::Item: Clone,
|
||||||
|
{
|
||||||
|
type Item = I::Item;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.needs_sep && self.inner.peek().is_some() {
|
||||||
|
self.needs_sep = false;
|
||||||
|
Some(self.separator.clone())
|
||||||
|
} else {
|
||||||
|
self.needs_sep = true;
|
||||||
|
self.inner.next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user