From 3e49453f3690a648dedcc094316d468446dc3cc7 Mon Sep 17 00:00:00 2001 From: light-ly Date: Wed, 2 Oct 2024 21:48:56 +0800 Subject: [PATCH] fix vhdl parse err --- src/core/vhdl_parser.rs | 306 ++++++++++++++++++++++++++++++---------- 1 file changed, 228 insertions(+), 78 deletions(-) diff --git a/src/core/vhdl_parser.rs b/src/core/vhdl_parser.rs index d648720..50989ec 100644 --- a/src/core/vhdl_parser.rs +++ b/src/core/vhdl_parser.rs @@ -75,52 +75,154 @@ fn parse_tokens(tokens: Vec) -> Vec { let token = &tokens[i]; match kind_str(token.kind) { "entity" => { + let start_pos = tokens[i].pos.range.start; i += 1; - let module = Module { - name: get_value(&tokens[i]), - params: Vec::new(), - ports: Vec::new(), - instances: Vec::new(), - range: Range { - start: Position { - line: tokens[i].pos.range.start.line + 1, - character: tokens[i].pos.range.start.character + 1 - }, - end: Position { - line: tokens[i].pos.range.end.line + 1, - character: tokens[i].pos.range.end.character + 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; } - }; - modules.push(module); + 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 { + 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" => { i += 1; 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") { i += 1; } i += 1; } ":" => { - if instance_type.contains(&get_value(&tokens[i+1])) { - let instance = Instance { - name: get_value(&tokens[i-1]), - inst_type: get_value(&tokens[i+1]), - instports: None, - instparams: None, - range: Range { - start: Position { - line: tokens[i-1].pos.range.start.line, - character: tokens[i-1].pos.range.start.character - }, - end: Position { - line: tokens[i+1].pos.range.start.line, - character: tokens[i+1].pos.range.start.character + if (i+2 < tokens.len()) && (kind_str(tokens[i+2].kind) != "use") { + if instance_type.contains(&get_value(&tokens[i+1])) { + let instance = Instance { + name: get_value(&tokens[i-1]), + inst_type: get_value(&tokens[i+1]), + 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+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" => { @@ -184,11 +286,14 @@ fn parse_port(tokens: &[Token], start: usize, is_map: bool) -> (Vec, usize "{identifier}" => { if is_map { 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 { - name: get_value(&tokens[i]), + name: "none".to_string(), dir_type: "none".to_string(), - net_type: get_value(&tokens[i+2]), + net_type: "none".to_string(), width: "none".to_string(), signed: "unsigned".to_string(), range: Range { @@ -202,41 +307,61 @@ fn parse_port(tokens: &[Token], start: usize, is_map: bool) -> (Vec, usize } }, }; - i += 2; ports.push(port); } 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 end_idx; - if get_value(&tokens[i+3]).contains("VECTOR") || get_value(&tokens[i+3]).contains("vector") { - let (width_str, index) = parse_width(&tokens, i+4); + let direction = if kind_str(tokens[i+1].kind) == "buffer" || kind_str(tokens[i+1].kind) == "out" { + 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 + "]"; - 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 { width = "1".to_string(); - end_idx = i+3; + end_idx = i+1; } 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) }; - let port = Port { - name: get_value(&tokens[i]), - dir_type: direction.to_string(), - net_type: get_value(&tokens[i+3]), - width, - signed: "unsigned".to_string(), - range: Range { - start: Position { - line: start_pos.line + 1, - character: start_pos.character + 1 + for tok in ports_token { + let port = Port { + name: get_value(&tok), + dir_type: direction.to_string(), + net_type: get_value(&tokens[i+1]), + width: width.to_string(), + signed: "unsigned".to_string(), + range: Range { + start: Position { + line: tok.pos.range.start.line + 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, - character: end_pos.character + 1 - } - }, - }; + }; + ports.push(port); + } i = end_idx; - ports.push(port); } } _ => {} @@ -292,6 +417,7 @@ fn parse_width(tokens: &[Token], start: usize) -> (String, usize) { #[allow(unused)] fn parse_parameters(tokens: &[Token], start: usize, is_map: bool) -> (Vec, usize) { + // println!("I am here, start {start}"); let mut params = Vec::new(); let mut i = start; let mut stack = Vec::new(); @@ -335,25 +461,49 @@ fn parse_parameters(tokens: &[Token], start: usize, is_map: bool) -> (Vec