Skip to content
Snippets Groups Projects
Commit 8c6bb891 authored by Pieter Donker's avatar Pieter Donker
Browse files

RTSD-79, add vhdl_style script

parent cf2bf1ed
No related branches found
No related tags found
No related merge requests found
Pipeline #48775 failed
#!/usr/bin/python3
from collections import OrderedDict
from argparse import ArgumentParser, RawTextHelpFormatter
from textwrap import dedent
from copy import copy
def main():
with open(args.filename, 'r') as fd:
old_data = fd.read()
parse = ParseData(old_data)
parse.parse()
new_data = parse.get_data()
if old_data != new_data:
print(f"fix {args.filename}")
with open(args.filename, 'w') as fd:
fd.write(new_data)
class ParseData:
def __init__(self, data):
self.types = Types()
self.operators = Operators()
self.reserved_words = ReservedWords()
self._comment = False
self._block_begin = ['--'] #, 'entity', 'generic', 'port', 'architecture']
self._block_end = [');', 'end']
self._data = data
self._new_data = []
self._last_ch = ''
self._word = ''
self._operator = ''
self._is_block_word = False
self._blocks = []
self._last_block = 'empty'
self._indent = 0
def get_data(self):
return ''.join(self._new_data)
# handle _word
def add_to_word(self, ch):
self._word += ch
self._is_block_word = self._word in self._block_begin
def get_word(self):
return self._word
def clear_word(self):
self._word = ''
self._is_block_word = False
def is_block_word(self):
return self._is_block_word
# handle _operator
def add_to_operator(self, ch):
self._operator += ch
def get_operator(self):
return self._operator
def clear_operator(self):
self._operator = ''
# handle _blocks info
def add_block(self, block):
self._blocks.append(block)
self._last_block = block
def delete_last_block(self):
self._blocks.pop()
try:
self._last_block = self._blocks[-1]
except IndexError:
self._last_block = 'empty'
def last_block(self):
return self._last_block
# handle new_data
def add_new_data(self, word):
for ch in word:
self._new_data.append(ch)
# parse data
def parse(self):
for ch in self._data:
# '--' is comment
if self._comment is True:
if ch == "\n":
self._comment = False
self.add_new_data(ch)
continue
# if ch == "\n":
# self.add_new_data("\n")
# continue
if self.get_operator() and (ch.isidentifier() or ch.isspace()):
self.add_new_data(self.get_operator())
self.clear_operator()
if ch.isidentifier():
self.add_to_word(ch)
continue
if self.get_word():
if self.types.is_valid(self.get_word()): # check if in types
self.add_new_data(self.get_word().lower())
elif self.operators.is_valid(self.get_word()): # check if in operators
self.add_new_data(self.get_word().lower())
elif self.reserved_words.is_valid(self.get_word()): # check if in reserved words
self.add_new_data(self.get_word().lower())
else:
self.add_new_data(self.get_word())
self.clear_word()
if self.operators.is_valid(ch):
self.add_to_operator(ch)
if self.get_operator() == '--':
self.add_new_data(self.get_operator())
self.clear_operator()
self._comment = True
continue
if self.get_operator():
self.add_new_data(self.get_operator())
self.clear_operator()
self.add_new_data(ch)
if self.is_block_word():
self.add_block(self.get_word())
continue
class Entity:
"""
entity [name] is
generic (
[g_*] : [type] := [val]; -- info
[g_*] : [type] := [val] -- info
);
port (
[port] : [dir] [type] := [val];
[port] : [dir] [type] := [val]
);
end [name];
"""
def __init__(self):
pass
class Types:
def __init__(self):
self.types = ["bit", "bit_vector", "integer", "natural", "positive", "boolean", "string",
"character", "real", "time", "delay_length",
"std_ulogic", "std_ulogic_vector", "std_logic", "std_logic_vector"]
def is_valid(self, val):
if val.lower() in self.types:
return True
return False
class Operators:
def __init__(self):
self.operators = ["**", "abs", "not", "*", "/", "mod", "rem", "+", "-", "+", "-", "&",
"sll", "srl", "sla", "sra", "rol", "ror", "=", "/=", "<", "<=", ">",
">=", "and", "or", "nand", "nor", "xor", "xnor"]
def is_valid(self, val):
if val.lower() in self.operators:
return True
return False
class ReservedWords:
def __init__(self):
self.reserved_words = ["abs", "access", "after", "alias", "all", "and", "architecture",
"array", "assert", "attribute", "begin", "block", "body", "buffer",
"bus", "case", "component", "configuration", "constant", "disconnect",
"downto", "else", "elsif", "end", "entity", "exit", "file", "for",
"function", "generate", "generic", "group", "guarded", "if", "impure",
"in", "inertial", "inout", "is", "label", "library", "linkage", "literal",
"loop", "map", "mod", "nand", "new", "next", "nor", "not", "null", "of",
"on", "open", "or", "others", "out", "package", "port", "postponed",
"procedure", "process", "pure", "range", "record", "register", "reject",
"rem", "report", "return", "rol", "ror", "select", "severity", "signal",
"shared", "sla", "sll", "sra", "srl", "subtype", "then", "to", "transport",
"type", "unaffected", "units", "until", "use", "variable", "wait", "when",
"while", "with", "xnor", "xor"]
def is_valid(self, val):
if val.lower() in self.reserved_words:
return True
return False
if __name__ == "__main__":
# Parse command line arguments
parser = ArgumentParser(
description="".join(dedent("""\
vhdl style fixer:
* vhdl_style_fix.py filename -h
\n""")),
formatter_class=RawTextHelpFormatter)
parser.add_argument('filename', type=str, help="filename to fix")
parser.add_argument('-v', '--verbose', action='store_true', help="verbose output")
args = parser.parse_args()
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment