fix vhdl parse err

This commit is contained in:
light-ly 2024-10-02 21:48:56 +08:00
parent 0a1eb5e080
commit 3e49453f36

View File

@ -75,52 +75,154 @@ fn parse_tokens(tokens: Vec<Token>) -> Vec<Module> {
let token = &tokens[i]; let token = &tokens[i];
match kind_str(token.kind) { match kind_str(token.kind) {
"entity" => { "entity" => {
let start_pos = tokens[i].pos.range.start;
i += 1; i += 1;
let module = Module { let entity_name = get_value(&tokens[i]);
name: get_value(&tokens[i]), // println!("entity name {:?}", entity_name);
params: Vec::new(), if (i >= 2 as usize) && (kind_str(tokens[i-2].kind) != "use") || (i < 2) {
ports: Vec::new(), let mut end = i;
instances: Vec::new(), while (
range: Range { end+1 < tokens.len()) &&
start: Position { !(kind_str(tokens[end].kind) == "end" &&
line: tokens[i].pos.range.start.line + 1, (kind_str(tokens[end+1].kind) == "entity" || get_value(&tokens[end+1]) == entity_name)) {
character: tokens[i].pos.range.start.character + 1 end += 1;
},
end: Position {
line: tokens[i].pos.range.end.line + 1,
character: tokens[i].pos.range.end.character + 1
}
} }
}; let end_pos = if end+1 < tokens.len() && get_value(&tokens[end+1]) == entity_name {
modules.push(module); i = end + 1;
tokens[end+2].pos.range.end
} else if end + 3 < tokens.len() {
i = end + 2;
tokens[end+3].pos.range.end
} else {
tokens[end].pos.range.end
};
let module = Module {
name: entity_name,
params: Vec::new(),
ports: Vec::new(),
instances: Vec::new(),
range: Range {
start: Position {
line: start_pos.line + 1,
character: start_pos.character + 1
},
end: Position {
line: end_pos.line + 1,
character: end_pos.character + 1
}
}
};
modules.push(module);
}
}
"architecture" => {
if (i >= 1 as usize) && (kind_str(tokens[i-1].kind) != "end") || (i < 1) {
let name = get_value(&tokens[i+3]);
if let None = modules.iter().find(|module| module.name == name) {
let start_pos = tokens[i].pos.range.start;
i += 1;
let arch_name = get_value(&tokens[i]);
// println!("arch name {:?}", arch_name);
let mut end = i;
while (end+1 < tokens.len()) &&
!(kind_str(tokens[end].kind) == "end" &&
(kind_str(tokens[end+1].kind) == "architecture" || get_value(&tokens[end+1]) == arch_name)) {
end += 1;
}
let end_pos = if get_value(&tokens[end+1]) == arch_name {
// i = end + 2;
tokens[end+2].pos.range.end
} else if end + 3 < tokens.len() {
// i = end + 3;
tokens[end+3].pos.range.end
} else {
// i = end;
tokens[end].pos.range.end
};
let module = Module {
name,
params: Vec::new(),
ports: Vec::new(),
instances: Vec::new(),
range: Range {
start: Position {
line: start_pos.line + 1,
character: start_pos.character + 1
},
end: Position {
line: end_pos.line + 1,
character: end_pos.character + 1
}
}
};
modules.push(module);
}
}
}
"configuration" => {
i += 1;
while !(kind_str(tokens[i].kind) == "end" && kind_str(tokens[i+1].kind) == "configuration") {
i += 1;
}
i += 1;
}
"package" => {
i += 1;
// println!("get package");
while !(kind_str(tokens[i].kind) == "end" && kind_str(tokens[i+1].kind) == "package") {
i += 1;
}
i += 1;
} }
"component" => { "component" => {
i += 1; i += 1;
instance_type.insert(get_value(&tokens[i])); instance_type.insert(get_value(&tokens[i]));
// println!("instance {:?}", kind_str(tokens[i].kind));
while !(kind_str(tokens[i].kind) == "end" && kind_str(tokens[i+1].kind) == "component") { while !(kind_str(tokens[i].kind) == "end" && kind_str(tokens[i+1].kind) == "component") {
i += 1; i += 1;
} }
i += 1; i += 1;
} }
":" => { ":" => {
if instance_type.contains(&get_value(&tokens[i+1])) { if (i+2 < tokens.len()) && (kind_str(tokens[i+2].kind) != "use") {
let instance = Instance { if instance_type.contains(&get_value(&tokens[i+1])) {
name: get_value(&tokens[i-1]), let instance = Instance {
inst_type: get_value(&tokens[i+1]), name: get_value(&tokens[i-1]),
instports: None, inst_type: get_value(&tokens[i+1]),
instparams: None, instports: None,
range: Range { instparams: None,
start: Position { range: Range {
line: tokens[i-1].pos.range.start.line, start: Position {
character: tokens[i-1].pos.range.start.character line: tokens[i-1].pos.range.start.line + 1,
}, character: tokens[i-1].pos.range.start.character + 1
end: Position { },
line: tokens[i+1].pos.range.start.line, end: Position {
character: tokens[i+1].pos.range.start.character line: tokens[i+1].pos.range.start.line + 1,
character: tokens[i+1].pos.range.start.character + 1
}
} }
} };
}; modules.last_mut().unwrap().instances.push(instance);
modules.last_mut().unwrap().instances.push(instance); } else if kind_str(tokens[i+1].kind) == "entity" {
let instance = Instance {
name: get_value(&tokens[i-1]),
inst_type: get_value(&tokens[i+2]),
instports: None,
instparams: None,
range: Range {
start: Position {
line: tokens[i-1].pos.range.start.line + 1,
character: tokens[i-1].pos.range.start.character + 1
},
end: Position {
line: tokens[i+2].pos.range.start.line + 1,
character: tokens[i+2].pos.range.start.character + 1
}
}
};
modules.last_mut().unwrap().instances.push(instance);
i += 1;
}
} }
} }
"generic" => { "generic" => {
@ -184,11 +286,14 @@ fn parse_port(tokens: &[Token], start: usize, is_map: bool) -> (Vec<Port>, usize
"{identifier}" => { "{identifier}" => {
if is_map { if is_map {
let start_pos = tokens[i].pos.range.start; let start_pos = tokens[i].pos.range.start;
let end_pos = tokens[i+3].pos.range.end; while kind_str(tokens[i+1].kind) != ")" {
i += 1;
}
let end_pos = tokens[i].pos.range.end;
let port = Port { let port = Port {
name: get_value(&tokens[i]), name: "none".to_string(),
dir_type: "none".to_string(), dir_type: "none".to_string(),
net_type: get_value(&tokens[i+2]), net_type: "none".to_string(),
width: "none".to_string(), width: "none".to_string(),
signed: "unsigned".to_string(), signed: "unsigned".to_string(),
range: Range { range: Range {
@ -202,41 +307,61 @@ fn parse_port(tokens: &[Token], start: usize, is_map: bool) -> (Vec<Port>, usize
} }
}, },
}; };
i += 2;
ports.push(port); ports.push(port);
} else { } else {
let start_pos = tokens[i].pos.range.start; let mut ports_token = Vec::new();
while kind_str(tokens[i].kind) != ":" {
// println!("{:?}", kind_str(tokens[i].kind));
if kind_str(tokens[i].kind) == "{identifier}" {
ports_token.push(&tokens[i]);
}
i += 1;
}
// let start_pos = tokens[i].pos.range.start;
let width ; let width ;
let end_idx; let end_idx;
if get_value(&tokens[i+3]).contains("VECTOR") || get_value(&tokens[i+3]).contains("vector") { let direction = if kind_str(tokens[i+1].kind) == "buffer" || kind_str(tokens[i+1].kind) == "out" {
let (width_str, index) = parse_width(&tokens, i+4); i += 1;
"out"
} else if kind_str(tokens[i+1].kind) == "in" {
i += 1;
"in"
} else {
"unknown"
};
if kind_str(tokens[i+2].kind) == "(" {
let (width_str, index) = parse_width(&tokens, i+2);
width = "[".to_string() + &width_str + "]"; width = "[".to_string() + &width_str + "]";
end_idx = index; end_idx = index-1;
} else if kind_str(tokens[i+2].kind) == "range" {
width = "[".to_string() + &get_value(&tokens[i+3]) + ":" + &get_value(&tokens[i+5]) + "]";
end_idx = i+5;
} else { } else {
width = "1".to_string(); width = "1".to_string();
end_idx = i+3; end_idx = i+1;
} }
let end_pos = tokens[end_idx].pos.range.end; let end_pos = tokens[end_idx].pos.range.end;
let direction = if kind_str(tokens[i+2].kind) == "buffer" { "out" } else { kind_str(tokens[i+2].kind) }; for tok in ports_token {
let port = Port { let port = Port {
name: get_value(&tokens[i]), name: get_value(&tok),
dir_type: direction.to_string(), dir_type: direction.to_string(),
net_type: get_value(&tokens[i+3]), net_type: get_value(&tokens[i+1]),
width, width: width.to_string(),
signed: "unsigned".to_string(), signed: "unsigned".to_string(),
range: Range { range: Range {
start: Position { start: Position {
line: start_pos.line + 1, line: tok.pos.range.start.line + 1,
character: start_pos.character + 1 character: tok.pos.range.start.character + 1
},
end: Position {
line: end_pos.line + 1,
character: end_pos.character + 1
}
}, },
end: Position { };
line: end_pos.line + 1, ports.push(port);
character: end_pos.character + 1 }
}
},
};
i = end_idx; i = end_idx;
ports.push(port);
} }
} }
_ => {} _ => {}
@ -292,6 +417,7 @@ fn parse_width(tokens: &[Token], start: usize) -> (String, usize) {
#[allow(unused)] #[allow(unused)]
fn parse_parameters(tokens: &[Token], start: usize, is_map: bool) -> (Vec<Parameter>, usize) { fn parse_parameters(tokens: &[Token], start: usize, is_map: bool) -> (Vec<Parameter>, usize) {
// println!("I am here, start {start}");
let mut params = Vec::new(); let mut params = Vec::new();
let mut i = start; let mut i = start;
let mut stack = Vec::new(); let mut stack = Vec::new();
@ -335,25 +461,49 @@ fn parse_parameters(tokens: &[Token], start: usize, is_map: bool) -> (Vec<Parame
i += 2; i += 2;
params.push(param); params.push(param);
} else { } else {
let start_pos = tokens[i].pos.range.start; let mut parameters = Vec::new();
let end_pos = tokens[i+4].pos.range.end; while kind_str(tokens[i].kind) != ":" {
let param = Parameter { // println!("{:?}", kind_str(tokens[i].kind));
name: get_value(&tokens[i]), if kind_str(tokens[i].kind) == "{identifier}" {
net_type: get_value(&tokens[i+2]), parameters.push(&tokens[i]);
init: get_value(&tokens[i+4]), }
range: Range { i += 1;
start: Position { }
line: start_pos.line + 1, let net_type = get_value(&tokens[i+1]);
character: start_pos.character + 1 let init = if kind_str(tokens[i+2].kind) == ":=" {
}, get_value(&tokens[i+3])
end: Position { } else {
line: end_pos.line + 1, "unknown".to_string()
character: end_pos.character + 1
}
},
}; };
i += 4; let end_pos = if kind_str(tokens[i+2].kind) == ":=" {
params.push(param); tokens[i+2].pos.range.end
} else {
tokens[i+1].pos.range.end
};
i = if kind_str(tokens[i+2].kind) == ":=" {
i + 3
} else {
i + 1
};
for param_token in parameters {
let start_pos = param_token.pos.range.start;
let param = Parameter {
name: get_value(param_token),
net_type: net_type.to_string(),
init: init.to_string(),
range: Range {
start: Position {
line: start_pos.line + 1,
character: start_pos.character + 1
},
end: Position {
line: end_pos.line + 1,
character: end_pos.character + 1
}
},
};
params.push(param);
}
} }
} }
_ => {} _ => {}