gtp_parser_generator/
lexer.rs1use 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 }
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}