Source code for pyIPCMI.Parser.FilesCodeDOM

# EMACS settings: -*-	tab-width: 2; indent-tabs-mode: t; python-indent-offset: 2 -*-
# vim: tabstop=2:shiftwidth=2:noexpandtab
# kate: tab-width 2; replace-tabs off; indent-width 2;
#
# ==============================================================================
# Authors:          Patrick Lehmann
#                   Martin Zabel
#
# Python Module:    TODO
#
# License:
# ==============================================================================
# Copyright 2017-2018 Patrick Lehmann - Bötzingen, Germany
# Copyright 2007-2016 Technische Universität Dresden - Germany
#                     Chair of VLSI-Design, Diagnostics and Architecture
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
#
# load dependencies
from lib.Parser     import MismatchingParserResult, MatchingParserResult, GreedyMatchingParserResult, StartOfDocumentToken
from lib.Parser     import SpaceToken, CharacterToken, StringToken, NumberToken
from lib.CodeDOM    import AndExpression, OrExpression, XorExpression, NotExpression, InExpression, NotInExpression, Literal, BinaryExpression
from lib.CodeDOM    import EmptyLine, CommentLine, BlockedStatement as BlockedStatementBase, ExpressionChoice
from lib.CodeDOM    import EqualExpression, UnequalExpression, LessThanExpression, LessThanEqualExpression, GreaterThanExpression, GreaterThanEqualExpression
from lib.CodeDOM    import Statement, BlockStatement, ConditionalBlockStatement, Function, Expression, ListElement
from lib.CodeDOM    import StringLiteral, IntegerLiteral, Identifier


__api__ = [
	'BlockedStatement',
	'IfThenElseExpressions', 'ListElementExpressions', 'PathExpressions',
	'ListConstructorExpression',
	'SubDirectoryExpression',
	'ConcatenateExpression',
	'ExistsFunction',
	'VHDLStatement', 'VerilogStatement', 'CocotbStatement',
	'ConstraintStatement',
	'LDCStatement', 'SDCStatement', 'UCFStatement', 'XDCStatement',
	'InterpolateLiteral',
	'PathStatement',
	'ReportStatement',
	'LibraryStatement',
	'IncludeStatement',
	'IfStatement', 'ElseIfStatement', 'ElseStatement', 'IfElseIfElseStatement',
	'Document'
]
__all__ = __api__


DEBUG =   False#True

# ==============================================================================
# Forward declarations
# ==============================================================================
[docs]class BlockedStatement(BlockedStatementBase): _allowedStatements = []
[docs]class IfThenElseExpressions(ExpressionChoice): _allowedExpressions = []
[docs]class ListElementExpressions(ExpressionChoice): _allowedExpressions = []
# class ListConstructorExpression(ExpressionChoice): # _allowedExpressions = []
[docs]class PathExpressions(ExpressionChoice): _allowedExpressions = []
# ============================================================================== # Expressions # ============================================================================== NotExpression.__PARSER_EXPRESSIONS__ = IfThenElseExpressions EqualExpression.__PARSER_LHS_EXPRESSIONS__ = IfThenElseExpressions EqualExpression.__PARSER_RHS_EXPRESSIONS__ = IfThenElseExpressions UnequalExpression.__PARSER_LHS_EXPRESSIONS__ = IfThenElseExpressions UnequalExpression.__PARSER_RHS_EXPRESSIONS__ = IfThenElseExpressions LessThanExpression.__PARSER_LHS_EXPRESSIONS__ = IfThenElseExpressions LessThanExpression.__PARSER_RHS_EXPRESSIONS__ = IfThenElseExpressions LessThanEqualExpression.__PARSER_LHS_EXPRESSIONS__ = IfThenElseExpressions LessThanEqualExpression.__PARSER_RHS_EXPRESSIONS__ = IfThenElseExpressions GreaterThanExpression.__PARSER_LHS_EXPRESSIONS__ = IfThenElseExpressions GreaterThanExpression.__PARSER_RHS_EXPRESSIONS__ = IfThenElseExpressions GreaterThanEqualExpression.__PARSER_LHS_EXPRESSIONS__ = IfThenElseExpressions GreaterThanEqualExpression.__PARSER_RHS_EXPRESSIONS__ = IfThenElseExpressions AndExpression.__PARSER_LHS_EXPRESSIONS__ = IfThenElseExpressions AndExpression.__PARSER_RHS_EXPRESSIONS__ = IfThenElseExpressions OrExpression.__PARSER_LHS_EXPRESSIONS__ = IfThenElseExpressions OrExpression.__PARSER_RHS_EXPRESSIONS__ = IfThenElseExpressions XorExpression.__PARSER_LHS_EXPRESSIONS__ = IfThenElseExpressions XorExpression.__PARSER_RHS_EXPRESSIONS__ = IfThenElseExpressions ListElement.__PARSER_LIST_ELEMENT_EXPRESSIONS__ = ListElementExpressions
[docs]class ListConstructorExpression(Expression): def __init__(self): super().__init__() self._list = [] @property def List(self): return self._list
[docs] def AddElement(self, element): self._list.append(element)
[docs] @classmethod def GetParser(cls): if DEBUG: print("init ListConstructorExpressionParser") # match for sign "[" token = yield if (not isinstance(token, CharacterToken)): raise MismatchingParserResult() if (token.Value != "["): raise MismatchingParserResult() # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield result = cls() parser = ListElementExpressions.GetParser() parser.send(None) try: while True: parser.send(token) token = yield except MatchingParserResult as ex: result.AddElement(ex.value) parser = cls.GetRepeatParser(result.AddElement, ListElement.GetParser) parser.send(None) try: while True: token = yield parser.send(token) except MatchingParserResult: pass # match for optional whitespace if isinstance(token, SpaceToken): token = yield # match for delimiter sign: \n if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("ListConstructorExpressionParser: Expected end of line or comment") if (token.Value != "]"): raise MismatchingParserResult("ListConstructorExpressionParser: Expected end of line or comment") # construct result if DEBUG: print("ListConstructorExpressionParser: matched {0}".format(result)) raise MatchingParserResult(result)
def __str__(self): buffer = "[{0}".format(self._list[0]) for item in self._list[1:]: buffer += ", {0}".format(item) buffer += "]" return buffer
InExpression.__PARSER_LHS_EXPRESSIONS__ = IfThenElseExpressions InExpression.__PARSER_RHS_EXPRESSIONS__ = ListConstructorExpression NotInExpression.__PARSER_LHS_EXPRESSIONS__ = IfThenElseExpressions NotInExpression.__PARSER_RHS_EXPRESSIONS__ = ListConstructorExpression
[docs]class SubDirectoryExpression(BinaryExpression): __PARSER_NAME__ = "SubDirectoryExpressionParser" __PARSER_LHS_EXPRESSIONS__ = PathExpressions __PARSER_RHS_EXPRESSIONS__ = PathExpressions __PARSER_OPERATOR__ = ("/",)
[docs]class ConcatenateExpression(BinaryExpression): __PARSER_NAME__ = "ConcatenateExpressionParser" __PARSER_LHS_EXPRESSIONS__ = PathExpressions __PARSER_RHS_EXPRESSIONS__ = PathExpressions __PARSER_OPERATOR__ = ("&",)
[docs]class ExistsFunction(Function): def __init__(self, expression): super().__init__() self._expression = expression @property def Expression(self): return self._expression
[docs] @classmethod def GetParser(cls): if DEBUG: print("init ExistsFunctionParser") # match for EXISTS keyword token = yield # if (not isinstance(token, StringToken)): raise MismatchingParserResult() # if (token.Value != "exists"): raise MismatchingParserResult() if (not isinstance(token, CharacterToken)): raise MismatchingParserResult() if (token.Value != "?"): raise MismatchingParserResult() # match for opening ( token = yield if (not isinstance(token, CharacterToken)): raise MismatchingParserResult() if (token.Value != "{"): raise MismatchingParserResult() # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for path expressions parser = PathExpressions.GetParser() parser.send(None) pathExpression = None try: while True: parser.send(token) token = yield except GreedyMatchingParserResult as ex: pathExpression = ex.value except MatchingParserResult as ex: pathExpression = ex.value token = yield # match for optional whitespace if isinstance(token, SpaceToken): token = yield # match for closing sign: } if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("ExistsFunctionParser: Expected end of line or comment") if (token.Value != "}"): raise MismatchingParserResult("ExistsFunctionParser: Expected end of line or comment") # construct result result = cls(pathExpression) if DEBUG: print("ExistsFunctionParser: matched {0}".format(result)) raise MatchingParserResult(result)
def __str__(self): return "exists{{{0!s}}}".format(self._expression)
IfThenElseExpressions.AddChoice(Identifier) IfThenElseExpressions.AddChoice(StringLiteral) IfThenElseExpressions.AddChoice(IntegerLiteral) IfThenElseExpressions.AddChoice(NotExpression) IfThenElseExpressions.AddChoice(ExistsFunction) IfThenElseExpressions.AddChoice(AndExpression) IfThenElseExpressions.AddChoice(OrExpression) IfThenElseExpressions.AddChoice(XorExpression) IfThenElseExpressions.AddChoice(EqualExpression) IfThenElseExpressions.AddChoice(UnequalExpression) IfThenElseExpressions.AddChoice(LessThanExpression) IfThenElseExpressions.AddChoice(LessThanEqualExpression) IfThenElseExpressions.AddChoice(GreaterThanExpression) IfThenElseExpressions.AddChoice(GreaterThanEqualExpression) IfThenElseExpressions.AddChoice(InExpression) IfThenElseExpressions.AddChoice(NotInExpression) ListElementExpressions.AddChoice(Identifier) ListElementExpressions.AddChoice(StringLiteral) ListElementExpressions.AddChoice(IntegerLiteral) # ============================================================================== # File Reference Statements # ==============================================================================
[docs]class VHDLStatement(Statement): def __init__(self, libraryName, pathExpression, commentText): super().__init__(commentText) self._libraryName = libraryName self._pathExpression = pathExpression @property def LibraryName(self): return self._libraryName @property def PathExpression(self): return self._pathExpression
[docs] @classmethod # mccabe:disable=MC0001 def GetParser(cls): # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for VHDL keyword if (not isinstance(token, StringToken)): raise MismatchingParserResult("VHDLParser: Expected VHDL keyword.") if (token.Value.lower() != "vhdl"): raise MismatchingParserResult("VHDLParser: Expected VHDL keyword.") # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult("VHDLParser: Expected whitespace before VHDL library name.") # match for identifier: library parser = Identifier.GetParser() parser.send(None) library = None try: while True: token = yield parser.send(token) except GreedyMatchingParserResult as ex: library = ex.value.Name except MatchingParserResult as ex: library = ex.value.Name token = yield # match for whitespace if (not isinstance(token, SpaceToken)): raise MismatchingParserResult("VHDLParser: Expected whitespace before VHDL fileName.") # match for a path: pathExpression parser = PathExpressions.GetParser() parser.send(None) pathExpression = None try: while True: token = yield parser.send(token) except GreedyMatchingParserResult as ex: pathExpression = ex.value except MatchingParserResult as ex: pathExpression = ex.value token = yield # match for optional whitespace if isinstance(token, SpaceToken): token = yield # match for delimiter sign: \n commentText = "" if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("VHDLParser: Expected end of line or comment") if (token.Value == "\n"): pass elif (token.Value == "#"): # match for any until line end while True: token = yield if (isinstance(token, CharacterToken) and (token.Value == "\n")): break commentText += token.Value else: raise MismatchingParserResult("VHDLParser: Expected end of line or comment") # construct result result = cls(library, pathExpression, commentText) raise MatchingParserResult(result)
def __str__(self, indent=0): if (self._commentText != ""): return "{0}VHDL {1} {2!s} # {3}".format((" " * indent), self._libraryName, self._pathExpression, self._commentText) else: return "{0}VHDL {1} {2!s}".format((" " * indent), self._libraryName, self._pathExpression)
[docs]class VerilogStatement(Statement): def __init__(self, pathExpression, commentText): super().__init__() self._pathExpression = pathExpression self._commentText = commentText @property def PathExpression(self): return self._pathExpression
[docs] @classmethod def GetParser(cls): # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for keyword: VERILOG if (not isinstance(token, StringToken)): raise MismatchingParserResult("VerilogParser: Expected VERILOG keyword.") if (token.Value.lower() != "verilog"): raise MismatchingParserResult("VerilogParser: Expected VERILOG keyword.") # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult("VerilogParser: Expected whitespace before Verilog fileName.") # match for string: fileName; use a StringLiteralParser to parse the pattern parser = PathExpressions.GetParser() parser.send(None) pathExpression = None try: while True: token = yield parser.send(token) except GreedyMatchingParserResult as ex: pathExpression = ex.value except MatchingParserResult as ex: pathExpression = ex.value token = yield # match for optional whitespace if isinstance(token, SpaceToken): token = yield # match for delimiter sign: \n commentText = "" if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("VerilogParser: Expected end of line or comment") if (token.Value == "\n"): pass elif (token.Value == "#"): # match for any until line end while True: token = yield if (isinstance(token, CharacterToken) and (token.Value == "\n")): break commentText += token.Value else: raise MismatchingParserResult("VerilogParser: Expected end of line or comment") # construct result result = cls(pathExpression, commentText) raise MatchingParserResult(result)
def __str__(self, indent=0): return "{0}Verilog {1!s}".format(" " * indent, self._pathExpression)
[docs]class CocotbStatement(Statement): def __init__(self, pathExpression, commentText): super().__init__() self._pathExpression = pathExpression self._commentText = commentText @property def PathExpression(self): return self._pathExpression
[docs] @classmethod def GetParser(cls): # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for keyword: COCOTB if (not isinstance(token, StringToken)): raise MismatchingParserResult("CocotbParser: Expected COCOTB keyword.") if (token.Value.lower() != "cocotb"): raise MismatchingParserResult("CocotbParser: Expected COCOTB keyword.") # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult("CocotbParser: Expected whitespace before Python fileName.") # match for string: fileName; use a StringLiteralParser to parse the pattern parser = PathExpressions.GetParser() parser.send(None) pathExpression = None try: while True: token = yield parser.send(token) except GreedyMatchingParserResult as ex: pathExpression = ex.value except MatchingParserResult as ex: pathExpression = ex.value token = yield # match for optional whitespace if isinstance(token, SpaceToken): token = yield # match for delimiter sign: \n commentText = "" if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("CocotbParser: Expected end of line or comment") if (token.Value == "\n"): pass elif (token.Value == "#"): # match for any until line end while True: token = yield if (isinstance(token, CharacterToken) and (token.Value == "\n")): break commentText += token.Value else: raise MismatchingParserResult("CocotbParser: Expected end of line or comment") # construct result result = cls(pathExpression, commentText) raise MatchingParserResult(result)
def __str__(self, indent=0): return "{0}Cocotb {1!s}".format(" " * indent, self._pathExpression)
[docs]class ConstraintStatement(Statement): __PARSER_NAME__ = None __PARSER_KEYWORD__ = None def __init__(self, pathExpression, commentText): super().__init__() self._pathExpression = pathExpression self._commentText = commentText @property def PathExpression(self): return self._pathExpression
[docs] @classmethod def GetParser(cls): # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for keyword: __PARSER_KEYWORD__ if (not isinstance(token, StringToken)): raise MismatchingParserResult(cls.__PARSER_NAME__ + ": Expected UCF keyword.") if (token.Value.lower() != cls.__PARSER_KEYWORD__): raise MismatchingParserResult(cls.__PARSER_NAME__ + ": Expected UCF keyword.") # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult(cls.__PARSER_NAME__ + ": Expected whitespace before UCF fileName.") # match for string: fileName; use a StringLiteralParser to parse the pattern parser = PathExpressions.GetParser() parser.send(None) pathExpression = None try: while True: token = yield parser.send(token) except GreedyMatchingParserResult as ex: pathExpression = ex.value except MatchingParserResult as ex: pathExpression = ex.value token = yield # match for optional whitespace if isinstance(token, SpaceToken): token = yield # match for delimiter sign: \n commentText = "" if (not isinstance(token, CharacterToken)): raise MismatchingParserResult(cls.__PARSER_NAME__ + ": Expected end of line or comment") if (token.Value == "\n"): pass elif (token.Value == "#"): # match for any until line end while True: token = yield if (isinstance(token, CharacterToken) and (token.Value == "\n")): break commentText += token.Value else: raise MismatchingParserResult(cls.__PARSER_NAME__ + ": Expected end of line or comment") # construct result result = cls(pathExpression, commentText) raise MatchingParserResult(result)
def __str__(self, indent=0): return "{indent}{kw} {filename!s}".format(indent=" " * indent, kw=self.__PARSER_KEYWORD__, filename=self._pathExpression)
[docs]class LDCStatement(ConstraintStatement): __PARSER_NAME__ = "LdcParser" __PARSER_KEYWORD__ = "ldc"
[docs]class SDCStatement(ConstraintStatement): __PARSER_NAME__ = "SdcParser" __PARSER_KEYWORD__ = "sdc"
[docs]class UCFStatement(ConstraintStatement): __PARSER_NAME__ = "UcfParser" __PARSER_KEYWORD__ = "ucf"
[docs]class XDCStatement(ConstraintStatement): __PARSER_NAME__ = "XdcParser" __PARSER_KEYWORD__ = "xdc"
[docs]class InterpolateLiteral(Literal): def __init__(self, sectionName, optionName): super().__init__() self._sectionName = sectionName self._optionName = optionName @property def SectionName(self): return self._sectionName @property def OptionName(self): return self._optionName
[docs] @classmethod def GetParser(cls): if DEBUG: print("init InterpolateLiteralParser") # match for opening ${ token = yield if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("InterpolateLiteralParser: ") if (token.Value != "$"): raise MismatchingParserResult("InterpolateLiteralParser: ") token = yield if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("InterpolateLiteralParser: ") if (token.Value != "{"): raise MismatchingParserResult("InterpolateLiteralParser: ") # match for interpolate value value = {False: "", True: ""} foundDelimiter = False while True: token = yield if isinstance(token, CharacterToken): if (token.Value == ":"): if (foundDelimiter is False): foundDelimiter = True else: raise MismatchingParserResult("InterpolateLiteralParser: ") elif (token.Value == "}"): break elif (token.Value in "._-"): value[foundDelimiter] += token.Value else: raise MismatchingParserResult("InterpolateLiteralParser: ") elif isinstance(token, (StringToken, NumberToken)): value[foundDelimiter] += token.Value else: raise MismatchingParserResult("InterpolateLiteralParser: ") if (foundDelimiter is True): sectionName = value[False] optionName = value[True] else: sectionName = None optionName = value[False] # construct result result = cls(sectionName, optionName) if DEBUG: print("InterpolateLiteralParser: matched {0}".format(result)) raise MatchingParserResult(result)
def __str__(self): if (self._sectionName is None): return "${{{optionName}}}".format(optionName=self._optionName) else: return "${{{sectionName}:{optionName}}}".format(sectionName=self._sectionName, optionName=self._optionName)
PathExpressions.AddChoice(Identifier) PathExpressions.AddChoice(StringLiteral) PathExpressions.AddChoice(InterpolateLiteral) PathExpressions.AddChoice(SubDirectoryExpression) PathExpressions.AddChoice(ConcatenateExpression)
[docs]class PathStatement(Statement): def __init__(self, variable, pathExpression, commentText): super().__init__() self._variable = variable self._pathExpression = pathExpression self._commentText = commentText @property def Variable(self): return self._variable @property def PathExpression(self): return self._pathExpression
[docs] @classmethod # mccabe:disable=MC0001 def GetParser(cls): # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for keyword: path if (not isinstance(token, StringToken)): raise MismatchingParserResult("PathParser: Expected UCF keyword.") if (token.Value.lower() != "path"): raise MismatchingParserResult("PathParser: Expected UCF keyword.") # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult("PathParser: Expected whitespace before variable.") # match for identifier: variable parser = Identifier.GetParser() parser.send(None) variable = None try: while True: token = yield parser.send(token) except GreedyMatchingParserResult as ex: variable = ex.value.Name except MatchingParserResult as ex: variable = ex.value.Name token = yield # match for optional whitespace if isinstance(token, SpaceToken): token = yield # match for delimiter sign: = if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("PathParser: Expected '=' sign before expression.") if (token.Value.lower() != "="): raise MismatchingParserResult("PathParser: Expected '=' sign before expression.") # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for expression # ========================================================================== parser = PathExpressions.GetParser() parser.send(None) pathExpression = None try: while True: parser.send(token) token = yield except GreedyMatchingParserResult as ex: pathExpression = ex.value except MatchingParserResult as ex: pathExpression = ex.value token = yield # match for delimiter sign: \n commentText = "" if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("PathParser: Expected end of line or comment") if (token.Value == "\n"): pass elif (token.Value == "#"): # match for any until line end while True: token = yield if (isinstance(token, CharacterToken) and (token.Value == "\n")): break commentText += token.Value else: raise MismatchingParserResult("PathParser: Expected end of line or comment") # construct result result = cls(variable, pathExpression, commentText) raise MatchingParserResult(result)
def __str__(self, indent=0): return "{indent}Path {var} := {expr!s}".format(indent=" " * indent, var=self._variable, expr=self._pathExpression) __repr__ = __str__
[docs]class ReportStatement(Statement): def __init__(self, message, commentText): super().__init__() self._message = message self._commentText = commentText @property def Message(self): return self._message
[docs] @classmethod def GetParser(cls): # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for keyword: VERILOG if (not isinstance(token, StringToken)): raise MismatchingParserResult("ReportParser: Expected REPORT keyword.") if (token.Value.lower() != "report"): raise MismatchingParserResult("ReportParser: Expected REPORT keyword.") # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult("ReportParser: Expected whitespace before report message.") # match for string: fileName; use a StringLiteralParser to parse the pattern parser = StringLiteral.GetParser() parser.send(None) message = None try: while True: token = yield parser.send(token) except MatchingParserResult as ex: message = ex.value.Value # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for delimiter sign: \n commentText = "" if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("ReportParser: Expected end of line or comment") if (token.Value == "\n"): pass elif (token.Value == "#"): # match for any until line end while True: token = yield if (isinstance(token, CharacterToken) and (token.Value == "\n")): break commentText += token.Value else: raise MismatchingParserResult("ReportParser: Expected end of line or comment") # construct result result = cls(message, commentText) raise MatchingParserResult(result)
def __str__(self, indent=0): return "{0}Report \"{1}\"".format(" " * indent, self._message)
[docs]class LibraryStatement(Statement): def __init__(self, library, pathExpression, commentText): super().__init__() self._library = library self._pathExpression = pathExpression self._commentText = commentText @property def Library(self): return self._library @property def PathExpression(self): return self._pathExpression
[docs] @classmethod # mccabe:disable=MC0001 def GetParser(cls): # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for keyword: LIBRARY if (not isinstance(token, StringToken)): raise MismatchingParserResult("LibraryParser: Expected LIBRARY keyword.") if (token.Value.lower() != "library"): raise MismatchingParserResult("LibraryParser: Expected LIBRARY keyword.") # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult("LibraryParser: Expected whitespace before LIBRARY library name.") # match for library name library = "" while True: token = yield if isinstance(token, StringToken): library += token.Value elif isinstance(token, NumberToken): library += token.Value elif (isinstance(token, CharacterToken)and (token.Value == "_")): library += token.Value else: break # match for whitespace if (not isinstance(token, SpaceToken)): raise MismatchingParserResult("LibraryParser: Expected whitespace before LIBRARY directoryName.") # match for string: fileName; use a StringLiteralParser to parse the pattern parser = PathExpressions.GetParser() parser.send(None) pathExpression = None try: while True: token = yield parser.send(token) except GreedyMatchingParserResult as ex: pathExpression = ex.value except MatchingParserResult as ex: pathExpression = ex.value token = yield # match for optional whitespace if isinstance(token, SpaceToken): token = yield # match for delimiter sign: \n commentText = "" if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("LibraryParser: Expected end of line or comment") if (token.Value == "\n"): pass elif (token.Value == "#"): # match for any until line end while True: token = yield if (isinstance(token, CharacterToken) and (token.Value == "\n")): break commentText += token.Value else: raise MismatchingParserResult("LibraryParser: Expected end of line or comment") # construct result result = cls(library, pathExpression, commentText) raise MatchingParserResult(result)
def __str__(self, indent=0): return "{0}Library {1} {2!s}".format(" " * indent, self._library, self._pathExpression)
[docs]class IncludeStatement(Statement): def __init__(self, pathExpression, commentText): super().__init__() self._pathExpression = pathExpression self._commentText = commentText @property def PathExpression(self): return self._pathExpression
[docs] @classmethod def GetParser(cls): # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for keyword: INCLUDE if (not isinstance(token, StringToken)): raise MismatchingParserResult("IncludeParser: Expected INCLUDE keyword.") if (token.Value.lower() != "include"): raise MismatchingParserResult("IncludeParser: Expected INCLUDE keyword.") # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult("IncludeParser: Expected whitespace before INCLUDE fileName.") # match for string: fileName; use a StringLiteralParser to parse the pattern parser = PathExpressions.GetParser() parser.send(None) pathExpression = None try: while True: token = yield parser.send(token) except GreedyMatchingParserResult as ex: pathExpression = ex.value except MatchingParserResult as ex: pathExpression = ex.value token = yield # match for optional whitespace if isinstance(token, SpaceToken): token = yield # match for delimiter sign: \n commentText = "" if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("IncludeParser: Expected end of line or comment") if (token.Value == "\n"): pass elif (token.Value == "#"): # match for any until line end while True: token = yield if (isinstance(token, CharacterToken) and (token.Value == "\n")): break commentText += token.Value else: raise MismatchingParserResult("IncludeParser: Expected end of line or comment") # construct result result = cls(pathExpression, commentText) raise MatchingParserResult(result)
def __str__(self, indent=0): return "{0}Include {1!s}".format(" " * indent, self._pathExpression)
# ============================================================================== # Conditional Statements # ==============================================================================
[docs]class IfStatement(ConditionalBlockStatement): def __init__(self, expression, commentText): super().__init__(expression) self._commentText = commentText
[docs] @classmethod # mccabe:disable=MC0001 def GetParser(cls): # match for IF clause # ========================================================================== # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for keyword: IF if (not isinstance(token, StringToken)): raise MismatchingParserResult() if (token.Value.lower() != "if"): raise MismatchingParserResult() # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult() # match for expression # ========================================================================== parser = IfThenElseExpressions.GetParser() parser.send(None) expressionRoot = None try: while True: token = yield parser.send(token) except MatchingParserResult as ex: expressionRoot = ex.value # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult() # match for keyword: THEN token = yield if (not isinstance(token, StringToken)): raise MismatchingParserResult() if (token.Value.lower() != "then"): raise MismatchingParserResult() # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for delimiter sign: \n commentText = "" if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("IfStatementParser: Expected end of line or comment") if (token.Value == "\n"): pass elif (token.Value == "#"): # match for any until line end while True: token = yield if (isinstance(token, CharacterToken) and (token.Value == "\n")): break commentText += token.Value else: raise MismatchingParserResult("IfStatementParser: Expected end of line or comment") # match for inner statements # ========================================================================== # construct result result = cls(expressionRoot, commentText) parser = cls.GetRepeatParser(result.AddStatement, BlockedStatement.GetParser) parser.send(None) try: while True: token = yield parser.send(token) except MatchingParserResult: raise MatchingParserResult(result)
def __str__(self, indent=0): buffer = (" " * indent) + "IfClause " + self._expression.__str__() for stmt in self._statements: buffer += "\n{0}".format(stmt.__str__(indent + 1)) return buffer
[docs]class ElseIfStatement(ConditionalBlockStatement): def __init__(self, expression, commentText): super().__init__(expression) self._commentText = commentText
[docs] @classmethod # mccabe:disable=MC0001 def GetParser(cls): # match for multiple ELSEIF clauses # ========================================================================== token = yield # match for optional whitespace if isinstance(token, SpaceToken): token = yield # match for keyword: ELSEIF if (not isinstance(token, StringToken)): raise MismatchingParserResult() if (token.Value.lower() != "elseif"): raise MismatchingParserResult() # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult() # match for expression # ========================================================================== parser = IfThenElseExpressions.GetParser() parser.send(None) expressionRoot = None try: while True: token = yield parser.send(token) except MatchingParserResult as ex: expressionRoot = ex.value # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult() # match for keyword: THEN token = yield if (not isinstance(token, StringToken)): raise MismatchingParserResult() if (token.Value.lower() != "then"): raise MismatchingParserResult() # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for delimiter sign: \n commentText = "" if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("ElseIfStatementParser: Expected end of line or comment") if (token.Value == "\n"): pass elif (token.Value == "#"): # match for any until line end while True: token = yield if (isinstance(token, CharacterToken) and (token.Value == "\n")): break commentText += token.Value else: raise MismatchingParserResult("ElseIfStatementParser: Expected end of line or comment") # match for inner statements # ========================================================================== # construct result result = cls(expressionRoot, commentText) parser = cls.GetRepeatParser(result.AddStatement, BlockedStatement.GetParser) parser.send(None) try: while True: token = yield parser.send(token) except MatchingParserResult: raise MatchingParserResult(result)
def __str__(self, indent=0): buffer = (" " * indent) + "ElseIfClause" + self._expression.__str__() for stmt in self._statements: buffer += "\n{0}".format(stmt.__str__(indent + 1)) return buffer
[docs]class ElseStatement(BlockStatement): def __init__(self, commentText): super().__init__() self._commentText = commentText
[docs] @classmethod def GetParser(cls): # match for ELSE clause # ========================================================================== # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for keyword: ELSE if (not isinstance(token, StringToken)): raise MismatchingParserResult() if (token.Value.lower() != "else"): raise MismatchingParserResult() # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for delimiter sign: \n commentText = "" if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("ElseStatementParser: Expected end of line or comment") if (token.Value == "\n"): pass elif (token.Value == "#"): # match for any until line end while True: token = yield if (isinstance(token, CharacterToken) and (token.Value == "\n")): break commentText += token.Value else: raise MismatchingParserResult("ElseStatementParser: Expected end of line or comment") # match for inner statements # ========================================================================== # construct result result = cls(commentText) parser = cls.GetRepeatParser(result.AddStatement, BlockedStatement.GetParser) parser.send(None) try: while True: token = yield parser.send(token) except MatchingParserResult: raise MatchingParserResult(result)
def __str__(self, indent=0): buffer = (" " * indent) + "ElseClause" for stmt in self._statements: buffer += "\n{0}".format(stmt.__str__(indent + 1)) return buffer
[docs]class IfElseIfElseStatement(Statement): def __init__(self): super().__init__() self._ifClause = None self._elseIfClauses = None self._elseClause = None @property def IfClause(self): return self._ifClause @IfClause.setter def IfClause(self, value): self._ifClause = value @property def ElseIfClauses(self): return self._elseIfClauses @ElseIfClauses.setter def ElseIfClauses(self, value): self._elseIfClauses = value @property def ElseClause(self): return self._elseClause @ElseClause.setter def ElseClause(self, value): self._elseClause = value
[docs] @classmethod # mccabe:disable=MC0001 def GetParser(cls): # construct result result = cls() # match for IF clause # ========================================================================== parser = IfStatement.GetParser() parser.send(None) try: while True: token = yield parser.send(token) except MatchingParserResult as ex: result.IfClause = ex.value # match for multiple ELSEIF clauses # ========================================================================== try: while True: parser = ElseIfStatement.GetParser() parser.send(None) try: parser.send(token) while True: token = yield parser.send(token) except MatchingParserResult as ex: if (result.ElseIfClauses is None): result.ElseIfClauses = [] result.ElseIfClauses.append(ex.value) except MismatchingParserResult as ex: pass # match for ELSE clause # ========================================================================== # match for inner statements parser = ElseStatement.GetParser() parser.send(None) try: parser.send(token) while True: token = yield parser.send(token) except MatchingParserResult as ex: result.ElseClause = ex.value except MismatchingParserResult as ex: pass # match for END IF clause # ========================================================================== # match for optional whitespace if isinstance(token, SpaceToken): token = yield # match for keyword: END if (not isinstance(token, StringToken)): raise MismatchingParserResult() if (token.Value.lower() != "end"): raise MismatchingParserResult() # match for whitespace token = yield if (not isinstance(token, SpaceToken)): raise MismatchingParserResult() # match for keyword: IF token = yield if (not isinstance(token, StringToken)): raise MismatchingParserResult() if (token.Value.lower() != "if"): raise MismatchingParserResult() # match for optional whitespace token = yield if isinstance(token, SpaceToken): token = yield # match for delimiter sign: \n # commentText = "" if (not isinstance(token, CharacterToken)): raise MismatchingParserResult("IfElseIfElseStatementParser: Expected end of line or comment") if (token.Value == "\n"): pass elif (token.Value == "#"): # match for any until line end while True: token = yield if (isinstance(token, CharacterToken) and (token.Value == "\n")): break # commentText += token.Value else: raise MismatchingParserResult("IfElseIfElseStatementParser: Expected end of line or comment") raise MatchingParserResult(result)
def __str__(self, indent=0): _indent = " " * indent buffer = _indent + "IfElseIfElseStatement\n" buffer += self.IfClause.__str__(indent + 1) if (self.ElseIfClauses is not None): for elseIf in self.ElseIfClauses: buffer += "\n" + elseIf.__str__(indent + 1) if (self.ElseClause is not None): buffer += "\n" + self.ElseClause.__str__(indent + 1) return buffer
[docs]class Document(BlockStatement):
[docs] @classmethod def GetParser(cls): result = cls() parser = cls.GetRepeatParser(result.AddStatement, BlockedStatement.GetParser) parser.send(None) token = yield if (not isinstance(token, StartOfDocumentToken)): raise MismatchingParserResult("Expected a StartOfDocumentToken, got {0!s}.".format(token)) try: while True: token = yield parser.send(token) except MatchingParserResult: raise MatchingParserResult(result)
def __str__(self, indent=0): buffer = " " * indent + "Document" for stmt in self._statements: buffer += "\n{0}".format(stmt.__str__(indent + 1)) return buffer
BlockedStatement.AddChoice(IncludeStatement) BlockedStatement.AddChoice(LibraryStatement) BlockedStatement.AddChoice(VHDLStatement) BlockedStatement.AddChoice(VerilogStatement) BlockedStatement.AddChoice(CocotbStatement) BlockedStatement.AddChoice(LDCStatement) BlockedStatement.AddChoice(SDCStatement) BlockedStatement.AddChoice(UCFStatement) BlockedStatement.AddChoice(XDCStatement) BlockedStatement.AddChoice(PathStatement) BlockedStatement.AddChoice(ReportStatement) BlockedStatement.AddChoice(IfElseIfElseStatement) BlockedStatement.AddChoice(CommentLine) BlockedStatement.AddChoice(EmptyLine)