## @file\r
# This file is used to check PCD logical expression\r
#\r
-# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
#\r
-# This program and the accompanying materials are licensed and made available \r
-# under the terms and conditions of the BSD License which accompanies this \r
-# distribution. The full text of the license may be found at \r
+# This program and the accompanying materials are licensed and made available\r
+# under the terms and conditions of the BSD License which accompanies this\r
+# distribution. The full text of the license may be found at\r
# http://opensource.org/licenses/bsd-license.php\r
#\r
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
and (IntChar < 0x23 or IntChar > 0x7e):\r
return False\r
PreChar = Char\r
- \r
+\r
# Last char cannot be \ if PreChar is not \\r
if LastChar == '\\' and PreChar == LastChar:\r
return False\r
self.Token = Token\r
self.Index = 0\r
self.Len = len(Token)\r
- \r
+\r
## SkipWhitespace\r
#\r
def SkipWhitespace(self):\r
if Char not in ' \t':\r
break\r
self.Index += 1\r
- \r
+\r
## IsCurrentOp\r
#\r
- # @param OpList: option list \r
- # \r
+ # @param OpList: option list\r
+ #\r
def IsCurrentOp(self, OpList):\r
self.SkipWhitespace()\r
- LetterOp = ["EQ", "NE", "GE", "LE", "GT", "LT", "NOT", "and", "AND", \r
+ LetterOp = ["EQ", "NE", "GE", "LE", "GT", "LT", "NOT", "and", "AND",\r
"or", "OR", "XOR"]\r
OpMap = {\r
'|' : '|',\r
'>' : '=',\r
'<' : '='\r
}\r
- \r
+\r
for Operator in OpList:\r
if not self.Token[self.Index:].startswith(Operator):\r
continue\r
- \r
+\r
self.Index += len(Operator)\r
Char = self.Token[self.Index : self.Index + 1]\r
\r
or (Operator in OpMap and OpMap[Operator] == Char):\r
self.Index -= len(Operator)\r
break\r
- \r
+\r
return True\r
- \r
+\r
return False\r
\r
## _LogicalExpressionParser\r
#\r
# @param _ExprBase: _ExprBase object\r
-# \r
+#\r
class _LogicalExpressionParser(_ExprBase):\r
#\r
# STRINGITEM can only be logical field according to spec\r
#\r
STRINGITEM = -1\r
- \r
+\r
#\r
# Evaluate to True or False\r
#\r
LOGICAL = 0\r
REALLOGICAL = 2\r
- \r
+\r
#\r
# Just arithmetic expression\r
#\r
ARITH = 1\r
- \r
+\r
def __init__(self, Token):\r
_ExprBase.__init__(self, Token)\r
self.Parens = 0\r
- \r
+\r
def _CheckToken(self, MatchList):\r
for Match in MatchList:\r
if Match and Match.start() == 0:\r
self.Token[self.Index:self.Index+Match.end()]\r
):\r
return False\r
- \r
+\r
self.Index += Match.end()\r
if self.Token[self.Index - 1] == '"':\r
return True\r
self.Token[self.Index:self.Index+1].isalnum():\r
self.Index -= Match.end()\r
return False\r
- \r
+\r
Token = self.Token[self.Index - Match.end():self.Index]\r
if Token.strip() in ["EQ", "NE", "GE", "LE", "GT", "LT",\r
"NOT", "and", "AND", "or", "OR", "XOR"]:\r
self.Index -= Match.end()\r
return False\r
- \r
+\r
return True\r
- \r
+\r
return False\r
- \r
+\r
def IsAtomicNumVal(self):\r
#\r
# Hex number\r
#\r
Match1 = re.compile(self.HEX_PATTERN).match(self.Token[self.Index:])\r
- \r
+\r
#\r
# Number\r
#\r
Match2 = re.compile(self.INT_PATTERN).match(self.Token[self.Index:])\r
- \r
+\r
#\r
# Macro\r
#\r
Match3 = re.compile(self.MACRO_PATTERN).match(self.Token[self.Index:])\r
- \r
+\r
#\r
# PcdName\r
#\r
Match4 = re.compile(self.PCD_PATTERN).match(self.Token[self.Index:])\r
- \r
+\r
return self._CheckToken([Match1, Match2, Match3, Match4])\r
- \r
+\r
\r
def IsAtomicItem(self):\r
#\r
# Macro\r
#\r
Match1 = re.compile(self.MACRO_PATTERN).match(self.Token[self.Index:])\r
- \r
+\r
#\r
# PcdName\r
#\r
Match2 = re.compile(self.PCD_PATTERN).match(self.Token[self.Index:])\r
- \r
+\r
#\r
# Quoted string\r
#\r
Match3 = re.compile(self.QUOTED_PATTERN).\\r
match(self.Token[self.Index:].replace('\\\\', '//').\\r
replace('\\\"', '\\\''))\r
- \r
+\r
return self._CheckToken([Match1, Match2, Match3])\r
- \r
+\r
## A || B\r
#\r
def LogicalExpression(self):\r
raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)\r
Ret = self.REALLOGICAL\r
return Ret\r
- \r
+\r
def SpecNot(self):\r
if self.IsCurrentOp(["NOT", "!", "not"]):\r
return self.SpecNot()\r
return self.Rel()\r
- \r
+\r
## A < B, A > B, A <= B, A >= B\r
#\r
def Rel(self):\r
raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)\r
Ret = self.REALLOGICAL\r
return Ret\r
- \r
+\r
## A + B, A - B\r
#\r
def Expr(self):\r
return Ret\r
\r
## Factor\r
- # \r
+ #\r
def Factor(self):\r
if self.IsCurrentOp(["("]):\r
self.Parens += 1\r
(self.Token, self.Token[self.Index:]))\r
self.Parens -= 1\r
return Ret\r
- \r
+\r
if self.IsAtomicItem():\r
if self.Token[self.Index - 1] == '"':\r
return self.STRINGITEM\r
else:\r
raise _ExprError(ST.ERR_EXPR_FACTOR % \\r
(self.Token[self.Index:], self.Token))\r
- \r
+\r
## IsValidLogicalExpression\r
#\r
def IsValidLogicalExpression(self):\r
self.INT = 2\r
self.IsParenHappen = False\r
self.IsLogicalOpHappen = False\r
- \r
+\r
## IsValidRangeExpression\r
#\r
def IsValidRangeExpression(self):\r
return False, ST.ERR_EXPR_RANGE % self.Token\r
except _ExprError as XExcept:\r
return False, XExcept.Error\r
- \r
+\r
self.SkipWhitespace()\r
if self.Index != self.Len:\r
return False, (ST.ERR_EXPR_RANGE % self.Token)\r
return True, ''\r
- \r
+\r
## RangeExpression\r
#\r
def RangeExpression(self):\r
raise _ExprError(ST.ERR_PAREN_NOT_USED % self.Token)\r
self.IsParenHappen = False\r
Ret = self.Unary()\r
- \r
+\r
if self.IsCurrentOp(['XOR']):\r
Ret = self.Unary()\r
- \r
+\r
return Ret\r
- \r
+\r
## Unary\r
#\r
def Unary(self):\r
if self.IsCurrentOp(["NOT"]):\r
return self.Unary()\r
- \r
+\r
return self.ValidRange()\r
- \r
+\r
## ValidRange\r
- # \r
+ #\r
def ValidRange(self):\r
Ret = -1\r
if self.IsCurrentOp(["("]):\r
raise _ExprError(ST.ERR_EXPR_RIGHT_PAREN % self.Token)\r
self.Parens -= 1\r
return Ret\r
- \r
+\r
if self.IsLogicalOpHappen:\r
raise _ExprError(ST.ERR_PAREN_NOT_USED % self.Token)\r
- \r
+\r
if self.IsCurrentOp(["LT", "GT", "LE", "GE", "EQ", "XOR"]):\r
IntMatch = \\r
re.compile(self.INT_PATTERN).match(self.Token[self.Index:])\r
def __init__(self, Token):\r
_ExprBase.__init__(self, Token)\r
self.NUM = 1\r
- \r
+\r
def IsValidListExpression(self):\r
if self.Len == 0:\r
return False, ST.ERR_EXPR_LIST_EMPTY\r
return False, (ST.ERR_EXPR_LIST % self.Token)\r
\r
return True, ''\r
- \r
+\r
def ListExpression(self):\r
Ret = -1\r
self.SkipWhitespace()\r
raise _ExprError(ST.ERR_EXPR_LIST % self.Token)\r
\r
return Ret\r
- \r
+\r
## _StringTestParser\r
#\r
class _StringTestParser(_ExprBase):\r
_ExprBase.__init__(self, Token)\r
\r
## IsValidStringTest\r
- # \r
+ #\r
def IsValidStringTest(self):\r
if self.Len == 0:\r
return False, ST.ERR_EXPR_EMPTY\r
return True, ''\r
\r
## StringItem\r
- # \r
+ #\r
def StringItem(self):\r
Match1 = re.compile(self.QUOTED_PATTERN)\\r
.match(self.Token[self.Index:].replace('\\\\', '//')\\r
(self.Token, self.Token[self.Index:]))\r
\r
## StringTest\r
- # \r
+ #\r
def StringTest(self):\r
self.StringItem()\r
if not self.IsCurrentOp(["==", "EQ", "!=", "NE"]):\r
##\r
# Check syntax of value list expression token\r
#\r
-# @param Token: value list expression token \r
+# @param Token: value list expression token\r
#\r
def IsValidListExpr(Token):\r
return _ValidListExpressionParser(Token).IsValidListExpression()\r
if not Valid:\r
Valid, Cause = IsValidLogicalExpr(Token, Flag)\r
if not Valid:\r
- return False, Cause \r
+ return False, Cause\r
return True, ""\r
\r
if __name__ == '__main__':\r
print(_LogicalExpressionParser('gCrownBayTokenSpaceGuid.PcdPciDevice1BridgeAddressLE0').IsValidLogicalExpression())\r
\r
\r
- \r
+\r