nom_lua/
name.rs

1// Copyright 2017 The nom-lua project developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use 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}