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,34 +75,116 @@ 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 entity_name = get_value(&tokens[i]);
// println!("entity name {:?}", entity_name);
if (i >= 2 as usize) && (kind_str(tokens[i-2].kind) != "use") || (i < 2) {
let mut end = i;
while (
end+1 < tokens.len()) &&
!(kind_str(tokens[end].kind) == "end" &&
(kind_str(tokens[end+1].kind) == "entity" || get_value(&tokens[end+1]) == entity_name)) {
end += 1;
}
let end_pos = if end+1 < tokens.len() && get_value(&tokens[end+1]) == entity_name {
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 { let module = Module {
name: get_value(&tokens[i]), name: entity_name,
params: Vec::new(), params: Vec::new(),
ports: Vec::new(), ports: Vec::new(),
instances: Vec::new(), instances: Vec::new(),
range: Range { range: Range {
start: Position { start: Position {
line: tokens[i].pos.range.start.line + 1, line: start_pos.line + 1,
character: tokens[i].pos.range.start.character + 1 character: start_pos.character + 1
}, },
end: Position { end: Position {
line: tokens[i].pos.range.end.line + 1, line: end_pos.line + 1,
character: tokens[i].pos.range.end.character + 1 character: end_pos.character + 1
} }
} }
}; };
modules.push(module); 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 (i+2 < tokens.len()) && (kind_str(tokens[i+2].kind) != "use") {
if instance_type.contains(&get_value(&tokens[i+1])) { if instance_type.contains(&get_value(&tokens[i+1])) {
let instance = Instance { let instance = Instance {
name: get_value(&tokens[i-1]), name: get_value(&tokens[i-1]),
@ -111,16 +193,36 @@ fn parse_tokens(tokens: Vec<Token>) -> Vec<Module> {
instparams: None, instparams: None,
range: Range { range: Range {
start: Position { start: Position {
line: tokens[i-1].pos.range.start.line, line: tokens[i-1].pos.range.start.line + 1,
character: tokens[i-1].pos.range.start.character character: tokens[i-1].pos.range.start.character + 1
}, },
end: Position { end: Position {
line: tokens[i+1].pos.range.start.line, line: tokens[i+1].pos.range.start.line + 1,
character: tokens[i+1].pos.range.start.character 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,32 +307,51 @@ 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 { end: Position {
line: end_pos.line + 1, line: end_pos.line + 1,
@ -235,9 +359,10 @@ fn parse_port(tokens: &[Token], start: usize, is_map: bool) -> (Vec<Port>, usize
} }
}, },
}; };
i = end_idx;
ports.push(port); ports.push(port);
} }
i = end_idx;
}
} }
_ => {} _ => {}
} }
@ -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,12 +461,36 @@ 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) != ":" {
// println!("{:?}", kind_str(tokens[i].kind));
if kind_str(tokens[i].kind) == "{identifier}" {
parameters.push(&tokens[i]);
}
i += 1;
}
let net_type = get_value(&tokens[i+1]);
let init = if kind_str(tokens[i+2].kind) == ":=" {
get_value(&tokens[i+3])
} else {
"unknown".to_string()
};
let end_pos = if kind_str(tokens[i+2].kind) == ":=" {
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 { let param = Parameter {
name: get_value(&tokens[i]), name: get_value(param_token),
net_type: get_value(&tokens[i+2]), net_type: net_type.to_string(),
init: get_value(&tokens[i+4]), init: init.to_string(),
range: Range { range: Range {
start: Position { start: Position {
line: start_pos.line + 1, line: start_pos.line + 1,
@ -352,10 +502,10 @@ fn parse_parameters(tokens: &[Token], start: usize, is_map: bool) -> (Vec<Parame
} }
}, },
}; };
i += 4;
params.push(param); params.push(param);
} }
} }
}
_ => {} _ => {}
} }
i += 1; i += 1;