use intern::intern;
use grammar::repr::*;
use lr1::lookahead::{Token, TokenSet};
use lr1::lookahead::Token::EOF;
use lr1::tls::Lr1Tls;
use test_util::{normalized_grammar};
use super::FirstSets;
pub fn nt(t: &str) -> Symbol {
Symbol::Nonterminal(NonterminalString(intern(t)))
}
pub fn term(t: &str) -> Symbol {
Symbol::Terminal(TerminalString::quoted(intern(t)))
}
fn la(t: &str) -> Token {
Token::Terminal(TerminalString::quoted(intern(t)))
}
fn first0(first: &FirstSets,
symbols: &[Symbol])
-> Vec<Token>
{
let v = first.first0(symbols);
v.iter().collect()
}
fn first1(first: &FirstSets,
symbols: &[Symbol],
lookahead: Token)
-> Vec<Token>
{
let v = first.first1(symbols, &TokenSet::from(lookahead));
v.iter().collect()
}
#[test]
fn basic_first1() {
let grammar = normalized_grammar(r#"
grammar;
A = B "C";
B: Option<u32> = {
"D" => Some(1),
=> None
};
X = "E"; // intentionally unreachable
"#);
let _lr1_tls = Lr1Tls::install(grammar.terminals.clone());
let first_sets = FirstSets::new(&grammar);
assert_eq!(
first1(&first_sets, &[nt("A")], EOF),
vec![la("C"), la("D")]);
assert_eq!(
first1(&first_sets, &[nt("B")], EOF),
vec![la("D"), EOF]);
assert_eq!(
first1(&first_sets, &[nt("B"), term("E")], EOF),
vec![la("D"), la("E")]);
assert_eq!(
first1(&first_sets, &[nt("B"), nt("X")], EOF),
vec![la("D"), la("E")]);
}
#[test]
fn basic_first0() {
let grammar = normalized_grammar(r#"
grammar;
A = B "C";
B: Option<u32> = {
"D" => Some(1),
=> None
};
X = "E"; // intentionally unreachable
"#);
let _lr1_tls = Lr1Tls::install(grammar.terminals.clone());
let first_sets = FirstSets::new(&grammar);
assert_eq!(
first0(&first_sets, &[nt("A")]),
vec![la("C"), la("D")]);
assert_eq!(
first0(&first_sets, &[nt("B")]),
vec![la("D"), EOF]);
assert_eq!(
first0(&first_sets, &[nt("B"), term("E")]),
vec![la("D"), la("E")]);
assert_eq!(
first0(&first_sets, &[nt("B"), nt("X")]),
vec![la("D"), la("E")]);
assert_eq!(
first0(&first_sets, &[nt("X")]),
vec![la("E")]);
}