1use ast::ASTNode;
10use nom::{alpha, digit};
11use std::str;
12use std::str::FromStr;
13
14named!(recognize_keyword, alt!(
15 tag!("and") |
16 tag!("break") |
17 tag!("do") |
18 tag!("else") |
19 tag!("elseif") |
20 tag!("end") |
21 tag!("false") |
22 tag!("for") |
23 tag!("function") |
24 tag!("goto") |
25 tag!("if") |
26 tag!("in") |
27 tag!("local") |
28 tag!("nil") |
29 tag!("not") |
30 tag!("or") |
31 tag!("repeat") |
32 tag!("return") |
33 tag!("then") |
34 tag!("true") |
35 tag!("until") |
36 tag!("while")
37));
38
39named!(pub parse_name<ASTNode>, map!(parse_valid_name, ASTNode::Name));
40
41named!(pub parse_valid_name<String>, map_res!(map_res!(do_parse!(
42 not!(recognize_keyword) >>
43 a: recognize!(preceded!(
44 many1!(alt!(tag!("_") | alpha)),
45 many0!(alt!(tag!("_") | alpha | digit)))) >> (a)),
46 str::from_utf8), FromStr::from_str));
47
48named!(pub parse_label<ASTNode>, map!(delimited!(
49 tag!("::"),
50 ws!(parse_valid_name),
51 tag!("::")),
52ASTNode::Label));
53
54
55named!(pub parse_namelist<ASTNode>, map!(
56 map!(do_parse!(
57 a: parse_name
58 >> b: many0!(preceded!(ws!(tag!(",")), parse_name))
59 >> ((a,b))
60 ), |(a, mut b): (_, Vec < ASTNode >) | { b.insert(0, a); b }),
61ASTNode::NameList));
62
63#[cfg(test)]
64mod tests {
65 use ast::ASTNode::*;
66
67 ast_test!(parse_valid_name_1, parse_valid_name, "il", "il".to_string());
68 ast_test!(parse_valid_name_2, parse_valid_name, "_il3", "_il3".to_string());
69 ast_panic_test!(parse_valid_name_3, parse_valid_name, "3lc_");
70 ast_panic_test!(parse_valid_name_4, parse_valid_name, "not");
71
72 ast_test!(parse_label_1, parse_label, "::il::", ast!(Label, "il".into()));
73 ast_test!(parse_label_2, parse_label, ":: z ::", ast!(Label, "z".into()));
74
75 ast_test!(parse_namelist_1, parse_namelist, "name1", ast!(NameList, vec![
76 ast!(Name, "name1".into()),
77 ]));
78 ast_test!(parse_namelist_2, parse_namelist, "name1 , name2", ast!(NameList, vec![
79 ast!(Name, "name1".into()),
80 ast!(Name, "name2".into()),
81 ]));
82 ast_test!(parse_namelist_3, parse_namelist, "name1 , name2, name3", ast!(NameList, vec![
83 ast!(Name, "name1".into()),
84 ast!(Name, "name2".into()),
85 ast!(Name, "name3".into()),
86 ]));
87 ast_test!(parse_namelist_4, parse_namelist, "a,b", ast!(NameList, vec![
88 ast!(Name, "a".into()),
89 ast!(Name, "b".into()),
90 ]));
91}