mirror of
https://github.com/fluencelabs/lalrpop
synced 2025-03-16 17:00:53 +00:00
macro expansion compiles now
This commit is contained in:
parent
3ddc0dfe02
commit
3a8992ab84
@ -198,7 +198,7 @@ impl Display for Symbol {
|
||||
Symbol::Nonterminal(ref s) =>
|
||||
write!(fmt, "{}", s),
|
||||
Symbol::Macro(ref m) =>
|
||||
write!(fmt, "{}<{}>", m.name, Sep(", ", &m.args)),
|
||||
write!(fmt, "{}", m),
|
||||
Symbol::Plus(ref s) =>
|
||||
write!(fmt, "{}+", s),
|
||||
Symbol::Question(ref s) =>
|
||||
@ -213,6 +213,18 @@ impl Display for Symbol {
|
||||
}
|
||||
}
|
||||
|
||||
impl MacroSymbol {
|
||||
pub fn canonical_form(&self) -> String {
|
||||
format!("{}", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for MacroSymbol {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
|
||||
write!(fmt, "{}<{}>", self.name, Sep(", ", &self.args))
|
||||
}
|
||||
}
|
||||
|
||||
struct Sep<S>(&'static str, S);
|
||||
|
||||
impl<'a,S:Display> Display for Sep<&'a Vec<S>> {
|
||||
|
@ -3,9 +3,10 @@ extern crate rusty_peg;
|
||||
|
||||
extern crate regex;
|
||||
|
||||
mod intern;
|
||||
mod parser;
|
||||
mod grammar;
|
||||
mod intern;
|
||||
mod normalize;
|
||||
mod parser;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
|
@ -1,7 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use intern::{intern, InternedString};
|
||||
use grammar::parse_tree::{Grammar, GrammarItem, MacroSymbol, Symbol};
|
||||
|
||||
pub fn expand_macros(input: pt::Grammar) {
|
||||
pub fn expand_macros(input: Grammar) {
|
||||
let Grammar { type_name, items } = input;
|
||||
let mut expander = MacroExpander::new();
|
||||
}
|
||||
@ -12,8 +13,8 @@ struct MacroExpander {
|
||||
}
|
||||
|
||||
impl MacroExpander {
|
||||
fn new(items: Vec<GrammarItem>) -> MacroExpander {
|
||||
MacroExpander { items: items, expansion_stack: Vec::new(), expansion_set: HashSet::new() }
|
||||
fn new() -> MacroExpander {
|
||||
MacroExpander { expansion_stack: Vec::new(), expansion_set: HashSet::new() }
|
||||
}
|
||||
|
||||
fn expand(&mut self, items: &mut Vec<GrammarItem>) {
|
||||
@ -22,7 +23,7 @@ impl MacroExpander {
|
||||
// Find any macro uses in items added since last round and
|
||||
// replace them in place with the expanded version:
|
||||
for item in &mut items[counter..] {
|
||||
self.replace(item);
|
||||
self.replace_item(item);
|
||||
}
|
||||
counter = items.len();
|
||||
|
||||
@ -33,7 +34,7 @@ impl MacroExpander {
|
||||
fn replace_item(&mut self, item: &mut GrammarItem) {
|
||||
match *item {
|
||||
GrammarItem::TokenType(..) => { }
|
||||
GrammarItem::Nonterminal(ref data) => {
|
||||
GrammarItem::Nonterminal(ref mut data) => {
|
||||
// Ignore macro definitions. They will be expanded in
|
||||
// due course.
|
||||
if !data.args.is_empty() {
|
||||
@ -41,31 +42,31 @@ impl MacroExpander {
|
||||
}
|
||||
|
||||
for alternative in &mut data.alternatives {
|
||||
self.replace_symbol(&mut alternative.symbol);
|
||||
self.replace_symbols(&mut alternative.expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_symbols(&mut self, symbols: &mut [Symbol]) {
|
||||
for symbol in symbols {
|
||||
self.replace_symbol(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_symbol(&mut self, symbol: &mut Symbol) {
|
||||
let key;
|
||||
|
||||
match *symbol {
|
||||
Symbol::Macro(ref mut macro) => {
|
||||
for sym in &mut macro.args {
|
||||
self.replace(sym);
|
||||
}
|
||||
|
||||
key = symbol.canonical_form();
|
||||
if self.expansion_set.insert(key) {
|
||||
self.expansion_stack.push(macro.clone());
|
||||
}
|
||||
}
|
||||
Symbol::Expr(ref mut syms) => {
|
||||
for sym in syms {
|
||||
Symbol::Macro(ref mut m) => {
|
||||
for sym in &mut m.args {
|
||||
self.replace_symbol(sym);
|
||||
}
|
||||
return;
|
||||
|
||||
key = intern(&m.canonical_form());
|
||||
if self.expansion_set.insert(key) {
|
||||
self.expansion_stack.push(m.clone());
|
||||
}
|
||||
}
|
||||
Symbol::Terminal(_) |
|
||||
Symbol::Nonterminal(_) => {
|
||||
@ -79,9 +80,13 @@ impl MacroExpander {
|
||||
self.replace_symbol(sym);
|
||||
return;
|
||||
}
|
||||
Symbol::Expr(ref mut syms) => {
|
||||
self.replace_symbols(syms);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// we only get here if this is a macro expansion
|
||||
*symbol = Symbol::Nonterminal(intern(key));
|
||||
*symbol = Symbol::Nonterminal(key);
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,6 @@
|
||||
|
||||
use grammar::parse_tree as pt;
|
||||
|
||||
pub fn normalize(input: pt::Grammar) -> Result<pt::Grammar> {
|
||||
}
|
||||
|
||||
// These are executed *IN ORDER*:
|
||||
|
||||
// Expands macros
|
||||
@ -22,7 +19,7 @@ pub fn normalize(input: pt::Grammar) -> Result<pt::Grammar> {
|
||||
//
|
||||
// AFTER THIS POINT: No more macros, macro references, or guarded
|
||||
// alternatives, though type indirections may occur.
|
||||
// mod macro_expand;
|
||||
mod macro_expand;
|
||||
|
||||
// Computes types where the user omitted them (or
|
||||
// from macro byproducts).
|
||||
|
Loading…
x
Reference in New Issue
Block a user