add include and define parse

This commit is contained in:
light-ly 2024-09-22 23:17:13 +08:00
parent bcb5788cf2
commit 4b6f6a365d
4 changed files with 151 additions and 15 deletions

View File

@ -61,12 +61,65 @@ pub struct Module {
pub range: Range
}
#[derive(Debug, Serialize)]
pub struct DefineParam {
pub name: String,
pub value: String
}
#[derive(Debug, Serialize)]
pub struct Define {
name: String,
replacement: String,
range: Range,
params: Vec<DefineParam>
}
#[derive(Debug, Serialize)]
pub struct Include {
pub path: String,
pub range: Range
}
#[derive(Debug, Serialize)]
pub struct Error {
severity: String,
message: String,
source: String,
range: Position,
running_mode: Option<String>,
running_phase: Option<String>,
}
#[derive(Debug, Serialize)]
pub struct Macro {
pub defines: Vec<Define>,
pub includes: Vec<Include>,
pub errors: Vec<Error>,
pub invalid: Vec<Range>
}
#[derive(Debug, Serialize)]
pub struct FastHdlparam {
pub fast: Vec<Module>
pub fast_macro: Macro,
pub content: Vec<Module>
}
impl FastHdlparam {
pub fn add_define(&mut self, name: &str, replacement: &str, start_line: u32, start_character: u32,
end_line: u32, end_character: u32, params: Vec<DefineParam>) {
let define = Define {
name: name.to_string(),
replacement: replacement.to_string(),
range: Range {
start: Position { line: start_line, character: start_character },
end: Position { line: end_line, character: end_character }
},
params
};
self.fast_macro.defines.push(define);
}
pub fn new_module(&mut self, name: &str, line: u32, character: u32, end_character: u32) {
let module = Module {
name: name.to_string(),
@ -82,12 +135,12 @@ impl FastHdlparam {
}
}
};
self.fast.push(module);
self.content.push(module);
}
pub fn add_parameter(&mut self, name: &str, net_type: &str, init: &str,
start_line: u32, start_character: u32, end_line: u32, end_character: u32) {
let last_module = self.fast.last_mut().unwrap();
let last_module = self.content.last_mut().unwrap();
let parameter = Parameter {
name: name.to_string(),
net_type: net_type.to_string(),
@ -106,7 +159,7 @@ impl FastHdlparam {
pub fn add_port(&mut self, name: &str, dir_type: &str, net_type: &str, width: &str,
start_line: u32, start_character: u32, end_line: u32, end_character: u32) {
let last_module = self.fast.last_mut().unwrap();
let last_module = self.content.last_mut().unwrap();
let port = Port {
name: name.to_string(),
dir_type: dir_type.to_string(),
@ -129,7 +182,7 @@ impl FastHdlparam {
pub fn add_instance(&mut self, name: &str, inst_type: &str, line: u32, character: u32, end_character: u32,
param_start_line: u32, param_start_character: u32, param_end_line: u32, param_end_character: u32,
port_start_line: u32, port_start_character: u32, port_end_line: u32, port_end_character: u32 ) {
let last_module = self.fast.last_mut().unwrap();
let last_module = self.content.last_mut().unwrap();
let instance = Instance {
name: name.to_string(),
inst_type: inst_type.to_string(),
@ -174,10 +227,10 @@ impl FastHdlparam {
}
pub fn print_fast(&self) {
if self.fast.is_empty() {
if self.content.is_empty() {
println!("none module");
} else {
for module in &self.fast {
for module in &self.content {
println!("module {}", module.name);
if !module.params.is_empty() {
println!(" params:");

View File

@ -1,7 +1,9 @@
use std::collections::HashMap;
use std::fs::File;
use std::io::BufRead;
use std::{collections::HashMap, io::BufReader};
use std::path::PathBuf;
use sv_parser::{parse_sv, unwrap_node, ConstantMintypmaxExpression, GateInstantiation, ListOfParameterAssignments, ListOfPortConnections, Locate, PackedDimensionRange, RefNode, SyntaxTree};
use super::fast_hdlparam::FastHdlparam;
use super::fast_hdlparam::{FastHdlparam, Macro};
pub fn sv_parser(path: &str) -> Option<FastHdlparam> {
// The path of SystemVerilog source file
@ -13,16 +15,22 @@ pub fn sv_parser(path: &str) -> Option<FastHdlparam> {
let result = parse_sv(&path, &defines, &includes, false, true);
if let Ok((syntax_tree, _)) = result {
let hdlparam = make_fast_from_syntaxtree(syntax_tree);
let hdlparam = make_fast_from_syntaxtree(syntax_tree, path);
return Some(hdlparam);
}
None
}
pub fn make_fast_from_syntaxtree(syntax_tree: SyntaxTree) -> FastHdlparam {
pub fn make_fast_from_syntaxtree(syntax_tree: SyntaxTree, path: PathBuf) -> FastHdlparam {
let mut hdlparam = FastHdlparam {
fast: Vec::new()
fast_macro: Macro {
defines: Vec::new(),
errors: Vec::new(),
includes: get_includes(path),
invalid: Vec::new()
},
content: Vec::new()
};
let mut ansi_port_last_dir = "";
@ -32,6 +40,40 @@ pub fn make_fast_from_syntaxtree(syntax_tree: SyntaxTree) -> FastHdlparam {
// &SyntaxTree is iterable
for node in &syntax_tree {
match node {
RefNode::TextMacroDefinition(x) => {
let start = unwrap_node!(x, TextMacroDefinition).unwrap();
let start = get_identifier(start).unwrap();
let (start_line, start_character) = (start.line, get_column_by_offset(&content, start.offset));
let name = unwrap_node!(x, TextMacroName).unwrap();
let name = get_identifier(name).unwrap();
let name = syntax_tree.get_str(&name).unwrap();
let mut params_vec = Vec::new();
if let Some(RefNode::ListOfFormalArguments(x)) = unwrap_node!(x, ListOfFormalArguments) {
for node in x {
if let RefNode::FormalArgument(x) = node {
let param_name = unwrap_node!(x, SimpleIdentifier).unwrap();
let param_name = get_identifier(param_name).unwrap();
let param_name = syntax_tree.get_str(&param_name).unwrap();
let param_val = match unwrap_node!(x, DefaultText) {
Some(RefNode::DefaultText(x)) => syntax_tree.get_str(&x.nodes.0).unwrap(),
_ => "Unknown"
};
params_vec.push(crate::core::fast_hdlparam::DefineParam { name: param_name.to_string(), value: param_val.to_string() });
}
}
}
let replacement = match unwrap_node!(x, MacroText) {
Some(RefNode::MacroText(x)) => Some(x.nodes.0),
_ => None
}.unwrap();
let (end_line, end_character) = (replacement.line, get_column_by_offset(&content, replacement.offset) + replacement.len);
let replacement = syntax_tree.get_str(&replacement).unwrap();
hdlparam.add_define(name, replacement, start_line, start_character as u32, end_line, end_character as u32, params_vec);
}
RefNode::ModuleDeclaration(x) => {
let id = unwrap_node!(x, ModuleIdentifier).unwrap();
let id = get_identifier(id).unwrap();
@ -490,6 +532,41 @@ fn get_identifier(node: RefNode) -> Option<Locate> {
}
}
fn get_includes(path: PathBuf) -> Vec<crate::core::fast_hdlparam::Include> {
let mut includes = Vec::new();
let file = File::open(path).unwrap();
let reader = BufReader::new(file);
for (line_number, line_content) in reader.lines().enumerate() {
let line_content = line_content.unwrap();
if line_content.trim().starts_with("`include") {
let parts: Vec<&str> = line_content.split_whitespace().collect();
if parts.len() >= 2 {
let path = parts[1];
let last_character = line_content.find(path).unwrap() + path.len();
includes.push(crate::core::fast_hdlparam::Include {
path: path.to_string(),
range: crate::core::fast_hdlparam::Range {
start: crate::core::fast_hdlparam::Position {
line: (line_number + 1) as u32, character: 1
},
end: crate::core::fast_hdlparam::Position {
line: (line_number + 1) as u32, character: last_character as u32
}
}
});
}
}
}
includes
}
fn get_column_by_offset(content: &[String], offset: usize) -> usize {
let mut current_offset = 0;

View File

@ -8,7 +8,13 @@ pub fn vhdl_parser(path: &str) -> FastHdlparam {
let path = PathBuf::from(path);
let mut hdlparam = FastHdlparam {
fast: Vec::new()
fast_macro: Macro {
defines: Vec::new(),
errors: Vec::new(),
includes: Vec::new(),
invalid: Vec::new()
},
content: Vec::new()
};
let parser = VHDLParser::new(VHDLStandard::VHDL2008);
@ -20,7 +26,7 @@ pub fn vhdl_parser(path: &str) -> FastHdlparam {
all_tockens.extend(tokens);
}
hdlparam.fast.extend(parse_tokens(all_tockens));
hdlparam.content.extend(parse_tokens(all_tockens));
hdlparam
}

View File

@ -113,7 +113,7 @@ pub fn do_fast(path: String) -> Result<FastHdlparam> {
);
if let Some(syntax_tree) = parse_result {
let hdlparam = make_fast_from_syntaxtree(syntax_tree);
let hdlparam = make_fast_from_syntaxtree(syntax_tree, path_buf);
return Ok(hdlparam);
}