gtp_parser_generator/
lexer.rs

1use pom::Parser;
2use pom::parser::*;
3
4use std::str::FromStr;
5
6
7fn space() -> Parser<u8, ()> {
8    one_of(b" \t").repeat(0..).discard()
9}
10
11fn comment() -> Parser<u8, ()> {
12    (sym(b'#') - none_of(b"\r\n").repeat(0..)).discard()
13}
14
15fn word() -> Parser<u8, String> {
16    is_a(non_control_non_space_non_comment).repeat(1..).map(utf8)
17}
18
19fn non_control_non_space_non_comment(term: u8) -> bool {
20    term > 32 && term < 127 && term != b'#'
21    //space is 32, lower is control characters
22    //127 is a control character, 128 and above are UTF-8 things
23}
24
25fn utf8(v: Vec<u8>) -> String {
26    String::from_utf8(v).unwrap()
27}
28
29pub fn command() -> Parser<u8, (Option<u8>, Vec<String>)> {
30    let integer = one_of(b"123456789") - one_of(b"0123456789").repeat(0..) | sym(b'0');
31    let number = integer.collect().convert(String::from_utf8).convert(|s|u8::from_str(&s));
32    number.opt() + (space() * word()).repeat(0..) - comment().opt()
33}
34
35#[test]
36fn command_comment() {
37    let input = ::pom::DataInput::new(b" \tfoo\t\t   bar#comment here");
38    let output = command().parse(&mut input.clone());
39    assert_eq!(output, Ok((None, vec!["foo".to_string(), "bar".to_string()])));
40}
41
42#[test]
43fn command_id() {
44    let input = ::pom::DataInput::new(b"12 quit");
45    let output = command().parse(&mut input.clone());
46    
47    assert_eq!(output, Ok((Some(12), vec!["quit".to_string()])));
48}