add include and define parse
This commit is contained in:
parent
bcb5788cf2
commit
4b6f6a365d
@ -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:");
|
||||
|
@ -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(¶m_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;
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user