Parser representations
This commit is contained in:
parent
9ed860383e
commit
0829b16fc9
@ -23,6 +23,10 @@ where
|
|||||||
fn name(&self) -> Option<String> {
|
fn name(&self) -> Option<String> {
|
||||||
self.name.clone()
|
self.name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn representation(&self) -> Option<Representation> {
|
||||||
|
self.repr.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, I, O, E> AnnotatedParser<P, I, O, E>
|
impl<P, I, O, E> AnnotatedParser<P, I, O, E>
|
||||||
|
@ -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<I, O, E> = Result<(O, I), (E, I)>;
|
pub type ParseResult<I, O, E> = Result<(O, I), (E, I)>;
|
||||||
|
|
||||||
@ -7,6 +7,9 @@ pub trait Parser<I, O, E> {
|
|||||||
fn name(&self) -> Option<String> {
|
fn name(&self) -> Option<String> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
fn representation(&self) -> Option<Representation> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, O, E, F> Parser<I, O, E> for F
|
impl<I, O, E, F> Parser<I, O, E> for F
|
||||||
|
@ -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, ()> {
|
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()) {
|
let p = move |input: &'a str| match input.get(0..expected.len()) {
|
||||||
Some(next) if next == expected => Ok((next, &input[expected.len()..])),
|
Some(next) if next == expected => Ok((next, &input[expected.len()..])),
|
||||||
_ => Err(((), input)),
|
_ => 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, ()> {
|
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()..])),
|
Some(ch) if ch == expected => Ok((expected, &input[ch.len_utf8()..])),
|
||||||
_ => Err(((), input)),
|
_ => 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, ()> {
|
pub fn one_of<'a>(items: &'static str) -> impl Parser<&'a str, char, ()> {
|
||||||
@ -64,5 +71,8 @@ mod tests {
|
|||||||
fn literals() {
|
fn literals() {
|
||||||
let parser = literal_char('f');
|
let parser = literal_char('f');
|
||||||
assert_eq!(Ok(('f', "unky")), parser.parse("funky"));
|
assert_eq!(Ok(('f', "unky")), parser.parse("funky"));
|
||||||
|
|
||||||
|
let repr = parser.representation().unwrap();
|
||||||
|
assert!(matches!(repr.production(), EBNF::CharTerminal('f')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use std::fmt;
|
|||||||
|
|
||||||
use crate::util::intersperse_option;
|
use crate::util::intersperse_option;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Representation {
|
pub struct Representation {
|
||||||
production_output: EBNF,
|
production_output: EBNF,
|
||||||
}
|
}
|
||||||
@ -12,18 +12,25 @@ impl Representation {
|
|||||||
self.production_output.to_string()
|
self.production_output.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn production(&self) -> EBNF {
|
||||||
|
self.production_output.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
production_output: EBNF::None,
|
production_output: EBNF::None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_production(production_output: EBNF) -> Self {
|
pub fn with_production(self, production_output: EBNF) -> Self {
|
||||||
Self { production_output }
|
Self {
|
||||||
|
production_output,
|
||||||
|
..self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum EBNF {
|
pub enum EBNF {
|
||||||
None,
|
None,
|
||||||
Nonterminal(String),
|
Nonterminal(String),
|
||||||
|
Loading…
Reference in New Issue
Block a user