kproc_parser/rust/
kattr.rs

1use std::collections::HashMap;
2
3use crate::kparser::KParserTracer;
4use crate::kproc_macros::KTokenStream;
5use crate::proc_macro::TokenTree;
6use crate::rust::ast_nodes::{AttrToken, AttributeToken, CondAttributeToken};
7
8pub fn check_and_parse_cond_attribute(
9    ast: &mut KTokenStream,
10    tracer: &dyn KParserTracer,
11) -> HashMap<String, AttrToken> {
12    tracer.log("check and parse an attribute");
13    tracer.log(format!("{:?}", ast.peek()).as_str());
14    let mut attrs = HashMap::new();
15    if ast.match_tok("#") {
16        let _ = ast.advance();
17        tracer.log(format!("{:?}", ast.peek()).as_str());
18
19        if ast.match_tok("!") {
20            let _ = ast.advance();
21            // check []
22        } else if ast.is_group() {
23            // check (
24            if let TokenTree::Group(_) = ast.lookup(2) {
25                let name = ast.advance();
26                let _ = ast.advance();
27                // keep parsing the conditional attribute
28                // FIXME: parse a sequence of attribute
29                let attr = check_and_parse_attribute(ast).unwrap();
30                let conf_attr = CondAttributeToken {
31                    name: name.to_owned(),
32                    value: attr,
33                };
34                attrs.insert(name.to_string(), AttrToken::CondAttr(conf_attr));
35            } else {
36                // parsing the normal attribute
37                // FIXME: parse a sequence of attribute
38                if let Some(attr) = check_and_parse_attribute(&mut ast.to_ktoken_stream()) {
39                    // consume group token
40                    let _ = ast.advance();
41                    attrs.insert(attr.name.to_string(), AttrToken::Attr(attr));
42                    return attrs;
43                }
44            }
45        }
46    }
47    attrs
48}
49
50pub fn check_and_parse_attribute(ast: &mut KTokenStream) -> Option<AttributeToken> {
51    let name = ast.advance();
52    // FIXME: check if it is a valid name
53    if !ast.is_end() && ast.match_tok("=") {
54        let _ = ast.advance();
55        let value = ast.advance();
56        return Some(AttributeToken {
57            name,
58            value: Some(value),
59        });
60    }
61    Some(AttributeToken { name, value: None })
62}