const LEFT_PAR : u32 = 2;const RIGHT_PAR : u32 = 3; const a : u32 = 4;
const A : u32 = 5;
const B : u32 = 6;
use llk::*;
#[test]
fn test_make_table() {
let mut parser =
LL1Parser::new(vec![
Rule::new(vec![
vec![LEFT_PAR, A, RIGHT_PAR],
vec![B]
]), Rule::new(vec![
vec![a]
]), ],
vec![&|_|{}, &|_|{}, &|_|{}],
A,
A
);
assert!( parser.make_table() == Ok(()) );
let table = parser.get_table();
let table_to_cmp = vec![
vec![u32::MAX ,u32::MAX , 0 , u32::MAX , 1], vec![u32::MAX ,u32::MAX ,u32::MAX , u32::MAX , 2] ];
println!("GOT : {:?}", *table);
println!("EXPECTED : {:?}", table_to_cmp);
for ilig in 0..table_to_cmp.len() {
for icol in 0..table_to_cmp[ilig].len() {
assert!(table[ilig][icol] == table_to_cmp[ilig][icol]);
}
}
}
#[test]
fn test_make_table_error_lf() {
let mut parser1 =
LL1Parser::new(vec![
Rule::new(vec![
vec![LEFT_PAR, A, RIGHT_PAR],
vec![LEFT_PAR]
]), Rule::new(vec![
vec![a]
]), ],
vec![&|_|{}, &|_|{}, &|_|{}],
A,
A
);
if let Err(err_msg) = parser1.make_table() {
let expected_msg = format!("Left factorisation error for the 0th rule (derivation 1).",);
println!("GOT {}", err_msg);
println!("EXPECTED {}", expected_msg);
assert!(err_msg == expected_msg);
} else {
panic!("Error expected");
}
let mut parser2 =
LL1Parser::new(vec![
Rule::new(vec![
vec![LEFT_PAR, A, RIGHT_PAR],
vec![B]
]), Rule::new(vec![
vec![LEFT_PAR]
]), ],
vec![&|_|{}, &|_|{}, &|_|{}],
A,
A
);
if let Err(err_msg) = parser2.make_table() {
let expected_msg = format!("Left factorisation error for the rule {}", A);
println!("GOT {}", err_msg);
println!("EXPECTED {}", err_msg);
assert!(err_msg == expected_msg);
} else {
panic!("Error expected");
}
}
#[test]
fn test_make_table_error_lr() {
let mut parser1 =
LL1Parser::new(vec![
Rule::new(vec![
vec![A],
vec![LEFT_PAR, A, RIGHT_PAR]
]), Rule::new(vec![
vec![a]
]), ],
vec![&|_|{}, &|_|{}, &|_|{}],
A,
A
);
if let Err(err_msg) = parser1.make_table() {
let expected_msg = format!("Left recursion error for the rule {}\n\tNote : From rule {}", A, A);
println!("GOT {}", err_msg);
println!("EXPECTED {}", expected_msg);
assert!(err_msg == expected_msg);
} else {
panic!("Error expected");
}
let mut parser2 =
LL1Parser::new(vec![
Rule::new(vec![
vec![B],
vec![LEFT_PAR, A, RIGHT_PAR],
]), Rule::new(vec![
vec![A]
]), ],
vec![&|_|{}, &|_|{}, &|_|{}],
A,
A
);
if let Err(err_msg) = parser2.make_table() {
let expected_msg = format!("Left recursion error for the rule {}\n\tNote : From rule {}\n\tNote : From rule {}", A, B, A);
println!("GOT {}", err_msg);
println!("EXPECTED {}", expected_msg);
assert!(err_msg == expected_msg);
} else {
panic!("Error expected");
}
}
#[test]
fn test_analyse() {
let mut parser =
LL1Parser::new(vec![
Rule::new(vec![
vec![LEFT_PAR, A, RIGHT_PAR],
vec![B]
]), Rule::new(vec![
vec![a]
]), ],
vec![&|_|{}, &|_|{}, &|_|{}],
A,
A
);
assert!( parser.make_table() == Ok(()) );
let l_p = Token::Terminal{id : LEFT_PAR, value : String::from("("), pos : 0};
let r_p = Token::Terminal{id : RIGHT_PAR, value : String::from(")"), pos : 0};
let a_ = Token::Terminal{id : a, value : String::from("a"), pos : 0};
let tokens = vec![l_p.clone(),
l_p.clone(),
l_p.clone(),
l_p.clone(),
a_.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
default_token::T_EOF.clone()
];
let mut ind = 0;
match parser.analyse_tokens(
|| {
if ind < tokens.len() {
ind += 1;
return Some(tokens[ind - 1].clone());
}
return None;
}
) {
Ok((_, warn)) => {
println!("{}", warn);
assert!(warn == String::from(""));
}
Err(e) => { panic!("Unexpected error : {:?}", e); }
}
}
#[test]
fn test_analyse_none() {
let mut parser =
LL1Parser::new(vec![
Rule::new(vec![
vec![LEFT_PAR, A, RIGHT_PAR],
vec![default_id::NONE]
]), ],
vec![&|_|{}, &|_|{}, &|_|{}],
A,
A
);
assert!( parser.make_table() == Ok(()) );
let l_p = Token::Terminal{id : LEFT_PAR, value : String::from("("), pos : 0};
let r_p = Token::Terminal{id : RIGHT_PAR, value : String::from(")"), pos : 0};
let tokens = vec![l_p.clone(),
l_p.clone(),
l_p.clone(),
l_p.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
default_token::T_EOF.clone()
];
let mut ind = 0;
match parser.analyse_tokens(
|| {
if ind < tokens.len() {
ind += 1;
return Some(tokens[ind - 1].clone());
}
return None;
}
) {
Ok((st, warn)) => {
println!("{st}");
println!("{warn}");
assert!(warn == String::from(""));
}
Err(e) => { panic!("Unexpected error : {:?}", e); }
}
}
#[test]
fn test_analyse_2() {
let mut parser =
LL1Parser::new(vec![
Rule::new(vec![
vec![LEFT_PAR, A, RIGHT_PAR],
vec![default_id::NONE]
]), Rule::new(vec![
vec![A, B],
vec![default_id::NONE]
]), ],
vec![&|_|{}, &|_|{}, &|_|{}, &|_|{}],
B,
A
);
match parser.make_table() {
Err(err) => {
println!("{err}");
panic!("Unexpected buggy grammar");
}
Ok(()) => {}
}
let l_p = Token::Terminal{id : LEFT_PAR, value : String::from("("), pos : 0};
let r_p = Token::Terminal{id : RIGHT_PAR, value : String::from(")"), pos : 0};
let tokens = vec![l_p.clone(),
l_p.clone(),
l_p.clone(),
l_p.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
l_p.clone(),
l_p.clone(),
l_p.clone(),
l_p.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
default_token::T_EOF.clone()
];
let mut ind = 0;
match parser.analyse_tokens(
|| {
if ind < tokens.len() {
ind += 1;
return Some(tokens[ind - 1].clone());
}
return None;
}
) {
Ok((st, warn)) => {
println!("{st}");
println!("{warn}");
assert!(warn == String::from(""));
}
Err(e) => { panic!("Unexpected error : {:?}", e); }
}
}
#[test]
fn test_analyse_warn() {
let mut parser =
LL1Parser::new(vec![
Rule::new(vec![
vec![LEFT_PAR, A, RIGHT_PAR],
vec![B]
]), Rule::new(vec![
vec![a]
]), ],
vec![&|_|{}, &|_|{}, &|_|{}],
A,
A
);
assert!( parser.make_table() == Ok(()) );
let l_p = Token::Terminal{id : LEFT_PAR, value : String::from("("), pos : 0};
let r_p = Token::Terminal{id : RIGHT_PAR, value : String::from(")"), pos : 0};
let a_ = Token::Terminal{id : a, value : String::from("a"), pos : 0};
let tokens = vec![l_p.clone(),
l_p.clone(),
l_p.clone(),
l_p.clone(),
a_.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
default_token::T_EOF.clone()
];
let mut ind = 0;
match parser.analyse_tokens(
|| {
if ind < tokens.len() {
ind += 1;
return Some(tokens[ind - 1].clone());
}
return None;
}
) {
Ok((_, warn)) => {
println!("{}", warn);
assert!(warn == String::from("Warning : Tokens remain unanalysed."));
}
Err(e) => { panic!("Unexpected error : {:?}", e); }
}
}
#[test]
fn test_analyse_error_ueof() {
let l_p = Token::Terminal{id : LEFT_PAR, value : String::from("("), pos : 0};
let r_p = Token::Terminal{id : RIGHT_PAR, value : String::from(")"), pos : 0};
let a_ = Token::Terminal{id : a, value : String::from("a"), pos : 0};
let mut parser =
LL1Parser::new(vec![
Rule::new(vec![
vec![LEFT_PAR, A, RIGHT_PAR],
vec![B]
]), Rule::new(vec![
vec![a]
]), ],
vec![&|_|{}, &|_|{}, &|_|{}],
A,
A
);
assert!( parser.make_table() == Ok(()) );
let expected_msg = String::from("Unexpected EOF");
let tokens = vec![l_p.clone(),
l_p.clone(),
l_p.clone(),
l_p.clone(),
a_.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
default_token::T_EOF.clone()
];
let mut ind = 0;
if let Err(err_msg) = parser.analyse_tokens(
|| {
if ind < tokens.len() {
ind += 1;
return Some(tokens[ind - 1].clone());
}
return None;
}
) {
println!("GOT {}", err_msg.additional_info);
println!("EXPECTED {}", expected_msg);
assert!(err_msg.additional_info == expected_msg);
} else {
panic!("Error expected");
}
}
#[test]
fn test_analyse_error_ueof_none() {
let l_p = Token::Terminal{id : LEFT_PAR, value : String::from("("), pos : 0};
let r_p = Token::Terminal{id : RIGHT_PAR, value : String::from(")"), pos : 0};
let mut parser =
LL1Parser::new(vec![
Rule::new(vec![
vec![LEFT_PAR, A, RIGHT_PAR],
vec![default_id::NONE]
]), ],
vec![&|_|{}, &|_|{}],
A,
A
);
assert!( parser.make_table() == Ok(()) );
let expected_msg = String::from("Unexpected EOF");
let tokens = vec![l_p.clone(),
l_p.clone(),
l_p.clone(),
l_p.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
default_token::T_EOF.clone()
];
let mut ind = 0;
if let Err(err_msg) = parser.analyse_tokens(
|| {
if ind < tokens.len() {
ind += 1;
return Some(tokens[ind - 1].clone());
}
return None;
}
) {
println!("GOT {}", err_msg.additional_info);
println!("EXPECTED {}", expected_msg);
assert!(err_msg.additional_info == expected_msg);
} else {
panic!("Error expected");
}
}
#[test]
fn test_analyse_error_1() {
let l_p = Token::Terminal{id : LEFT_PAR, value : String::from("("), pos : 0};
let r_p = Token::Terminal{id : RIGHT_PAR, value : String::from(")"), pos : 0};
let a_ = Token::Terminal{id : a, value : String::from("a"), pos : 0};
let mut parser =
LL1Parser::new(vec![
Rule::new(vec![
vec![LEFT_PAR, A, RIGHT_PAR],
vec![B]
]), Rule::new(vec![
vec![a]
]), ],
vec![&|_|{}, &|_|{}, &|_|{}],
A,
A
);
assert!( parser.make_table() == Ok(()) );
let expected_msg = format!(
"There is no rule which correspond to the derivation : Rule {} doesn't begin by token {}",
A,
RIGHT_PAR
);
let tokens = vec![r_p.clone(),
l_p.clone(),
l_p.clone(),
l_p.clone(),
a_.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
default_token::T_EOF.clone()
];
let mut ind = 0;
if let Err(err_msg) = parser.analyse_tokens(
|| {
if ind < tokens.len() {
ind += 1;
return Some(tokens[ind - 1].clone());
}
return None;
}
) {
println!("GOT {}", err_msg.additional_info);
println!("EXPECTED {}", expected_msg);
assert!(err_msg.additional_info == expected_msg);
} else {
panic!("Error expected");
}
}
#[test]
fn test_analyse_error_2() {
let l_p = Token::Terminal{id : LEFT_PAR, value : String::from("("), pos : 0};
let r_p = Token::Terminal{id : RIGHT_PAR, value : String::from(")"), pos : 0};
let a_ = Token::Terminal{id : a, value : String::from("a"), pos : 0};
let mut parser =
LL1Parser::new(vec![
Rule::new(vec![
vec![LEFT_PAR, A, RIGHT_PAR],
vec![B]
]), Rule::new(vec![
vec![a]
]), ],
vec![&|_|{}, &|_|{}, &|_|{}],
A,
A
);
assert!( parser.make_table() == Ok(()) );
let expected_msg = format!("Uncorresponding token : {} expected, found {}", RIGHT_PAR, a);
let tokens = vec![l_p.clone(),
l_p.clone(),
l_p.clone(),
l_p.clone(),
a_.clone(),
a_.clone(),
r_p.clone(),
r_p.clone(),
r_p.clone(),
default_token::T_EOF.clone()
];
let mut ind = 0;
if let Err(err_msg) = parser.analyse_tokens(
|| {
if ind < tokens.len() {
ind += 1;
return Some(tokens[ind - 1].clone());
}
return None;
}
) {
println!("GOT {}", err_msg.additional_info);
println!("EXPECTED {}", expected_msg);
assert!(err_msg.additional_info == expected_msg);
} else {
panic!("Error expected");
}
}