mirror of
https://github.com/fluencelabs/lalrpop
synced 2025-06-06 06:51:25 +00:00
Make a trait for lookahead
This commit is contained in:
parent
b0b7735bbc
commit
19a0852539
@ -3,34 +3,34 @@
|
||||
use collections::Map;
|
||||
use grammar::repr::*;
|
||||
use itertools::Itertools;
|
||||
use std::fmt::{Debug, Formatter, Error};
|
||||
use std::fmt::{Debug, Display, Formatter, Error};
|
||||
use std::rc::Rc;
|
||||
use util::Prefix;
|
||||
|
||||
use super::lookahead::Token;
|
||||
use super::lookahead::*;
|
||||
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Item<'grammar, L: Clone> {
|
||||
pub struct Item<'grammar, L: Lookahead> {
|
||||
pub production: &'grammar Production,
|
||||
/// the dot comes before `index`, so `index` would be 1 for X = A (*) B C
|
||||
pub index: usize,
|
||||
pub lookahead: L,
|
||||
}
|
||||
|
||||
pub type LR0Item<'grammar> = Item<'grammar, ()>;
|
||||
pub type LR0Item<'grammar> = Item<'grammar, Nil>;
|
||||
|
||||
pub type LR1Item<'grammar> = Item<'grammar, Token>;
|
||||
|
||||
impl<'grammar> Item<'grammar, ()> {
|
||||
impl<'grammar> Item<'grammar, Nil> {
|
||||
#[cfg(test)]
|
||||
pub fn lr0(production: &'grammar Production,
|
||||
index: usize)
|
||||
-> Self {
|
||||
Item { production: production, index: index, lookahead: () }
|
||||
Item { production: production, index: index, lookahead: Nil }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'grammar, L: Clone> Item<'grammar, L> {
|
||||
impl<'grammar, L: Lookahead> Item<'grammar, L> {
|
||||
pub fn prefix(&self) -> &'grammar [Symbol] {
|
||||
&self.production.symbols[..self.index]
|
||||
}
|
||||
@ -53,7 +53,7 @@ impl<'grammar, L: Clone> Item<'grammar, L> {
|
||||
}
|
||||
|
||||
pub fn to_lr0(&self) -> LR0Item<'grammar> {
|
||||
Item { production: self.production, index: self.index, lookahead: () }
|
||||
Item { production: self.production, index: self.index, lookahead: Nil }
|
||||
}
|
||||
|
||||
pub fn can_shift(&self) -> bool {
|
||||
@ -88,15 +88,15 @@ impl<'grammar, L: Clone> Item<'grammar, L> {
|
||||
pub struct StateIndex(pub usize);
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Items<'grammar, L: Clone> {
|
||||
pub struct Items<'grammar, L: Lookahead> {
|
||||
pub vec: Rc<Vec<Item<'grammar, L>>>
|
||||
}
|
||||
|
||||
pub type LR0Items<'grammar> = Items<'grammar, ()>;
|
||||
pub type LR0Items<'grammar> = Items<'grammar, Nil>;
|
||||
pub type LR1Items<'grammar> = Items<'grammar, Token>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct State<'grammar, L: Clone> {
|
||||
pub struct State<'grammar, L: Lookahead> {
|
||||
pub index: StateIndex,
|
||||
pub items: Items<'grammar, L>,
|
||||
pub tokens: Map<Token, Action<'grammar>>,
|
||||
@ -104,7 +104,7 @@ pub struct State<'grammar, L: Clone> {
|
||||
pub gotos: Map<NonterminalString, StateIndex>,
|
||||
}
|
||||
|
||||
pub type LR0State<'grammar> = State<'grammar, ()>;
|
||||
pub type LR0State<'grammar> = State<'grammar, Nil>;
|
||||
pub type LR1State<'grammar> = State<'grammar, Token>;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
@ -131,24 +131,18 @@ pub struct TableConstructionError<'grammar> {
|
||||
pub states: Vec<LR1State<'grammar>>,
|
||||
}
|
||||
|
||||
impl<'grammar, L: Clone+Debug> Debug for Item<'grammar, L> {
|
||||
impl<'grammar, L: Lookahead> Debug for Item<'grammar, L> {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
|
||||
let mut lookahead_debug = format!("{:?}", self.lookahead);
|
||||
if lookahead_debug != "()" {
|
||||
lookahead_debug = format!(" [{}]", lookahead_debug);
|
||||
} else {
|
||||
lookahead_debug = format!("");
|
||||
}
|
||||
try!(write!(fmt, "{} ={} (*){}",
|
||||
self.production.nonterminal,
|
||||
Prefix(" ", &self.production.symbols[..self.index]),
|
||||
Prefix(" ", &self.production.symbols[self.index..])));
|
||||
|
||||
write!(fmt, "{} ={} (*){}{}",
|
||||
self.production.nonterminal,
|
||||
Prefix(" ", &self.production.symbols[..self.index]),
|
||||
Prefix(" ", &self.production.symbols[self.index..]),
|
||||
lookahead_debug)
|
||||
self.lookahead.fmt_as_item_suffix(fmt)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Token {
|
||||
impl Display for Token {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
|
||||
match *self {
|
||||
Token::EOF => write!(fmt, "EOF"),
|
||||
@ -157,13 +151,19 @@ impl Debug for Token {
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Token {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
|
||||
write!(fmt, "{}", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for StateIndex {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
|
||||
write!(fmt, "S{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'grammar, L: Clone> State<'grammar, L> {
|
||||
impl<'grammar, L: Lookahead> State<'grammar, L> {
|
||||
/// Returns the set of symbols which must appear on the stack to
|
||||
/// be in this state. This is the *maximum* prefix of any item,
|
||||
/// basically.
|
||||
|
@ -2,6 +2,19 @@ use bit_set::{self, BitSet};
|
||||
use std::fmt::{Debug, Formatter, Error};
|
||||
use grammar::repr::*;
|
||||
|
||||
pub trait Lookahead: Clone + Debug + PartialEq + Eq + PartialOrd + Ord {
|
||||
fn fmt_as_item_suffix(&self, fmt: &mut Formatter) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Nil;
|
||||
|
||||
impl Lookahead for Nil {
|
||||
fn fmt_as_item_suffix(&self, _fmt: &mut Formatter) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// I have semi-arbitrarily decided to say that a "token" is either
|
||||
/// one of the terminals of our language, or else the pseudo-symbol
|
||||
/// EOF that represents "end of input".
|
||||
@ -11,6 +24,12 @@ pub enum Token {
|
||||
Terminal(TerminalString),
|
||||
}
|
||||
|
||||
impl Lookahead for Token {
|
||||
fn fmt_as_item_suffix(&self, fmt: &mut Formatter) -> Result<(), Error> {
|
||||
write!(fmt, " [{}]", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Token {
|
||||
pub fn unwrap_terminal(self) -> TerminalString {
|
||||
match self {
|
||||
|
@ -43,7 +43,7 @@ pub Ty: () = {
|
||||
// Ty = Ty -> Ty (*) (reduce)
|
||||
|
||||
assert!(conflict.production.symbols.len() == 3);
|
||||
let item = Item { production: conflict.production, index: 1, lookahead: () };
|
||||
let item = Item::lr0(conflict.production, 1);
|
||||
println!("item={:?}", item);
|
||||
let tracer = Tracer::new(&grammar, &states);
|
||||
let graph = tracer.backtrace_shift(conflict.state, item);
|
||||
|
@ -1,5 +1,6 @@
|
||||
use collections::{Map, map};
|
||||
use lr1::core::*;
|
||||
use lr1::lookahead::*;
|
||||
use lr1::example::*;
|
||||
use grammar::repr::*;
|
||||
use petgraph::{EdgeDirection, Graph};
|
||||
@ -102,7 +103,7 @@ impl<'grammar> Into<TraceGraphNode<'grammar>> for NonterminalString {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'grammar, L: Clone> Into<TraceGraphNode<'grammar>> for Item<'grammar, L> {
|
||||
impl<'grammar, L: Lookahead> Into<TraceGraphNode<'grammar>> for Item<'grammar, L> {
|
||||
fn into(self) -> TraceGraphNode<'grammar> {
|
||||
TraceGraphNode::Item(self.to_lr0())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user