]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
BaseTools: Refactor python except statements
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Library / ExpressionValidate.py
CommitLineData
4234283c
LG
1## @file\r
2# This file is used to check PCD logical expression\r
3#\r
421ccda3 4# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
4234283c
LG
5#\r
6# This program and the accompanying materials are licensed and made available \r
7# under the terms and conditions of the BSD License which accompanies this \r
8# distribution. The full text of the license may be found at \r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14'''\r
15ExpressionValidate\r
16'''\r
17\r
18##\r
19# Import Modules\r
20#\r
21import re\r
22from Logger import StringTable as ST\r
23\r
24## IsValidBareCString\r
25#\r
26# Check if String is comprised by whitespace(0x20), !(0x21), 0x23 - 0x7E\r
27# or '\n', '\t', '\f', '\r', '\b', '\0', '\\'\r
28#\r
29# @param String: string to be checked\r
30#\r
31def IsValidBareCString(String):\r
32 EscapeList = ['n', 't', 'f', 'r', 'b', '0', '\\', '"']\r
33 PreChar = ''\r
34 LastChar = ''\r
35 for Char in String:\r
36 LastChar = Char\r
37 if PreChar == '\\':\r
38 if Char not in EscapeList:\r
39 return False\r
40 if Char == '\\':\r
41 PreChar = ''\r
42 continue\r
43 else:\r
44 IntChar = ord(Char)\r
45 if IntChar != 0x20 and IntChar != 0x09 and IntChar != 0x21 \\r
46 and (IntChar < 0x23 or IntChar > 0x7e):\r
47 return False\r
48 PreChar = Char\r
49 \r
50 # Last char cannot be \ if PreChar is not \\r
51 if LastChar == '\\' and PreChar == LastChar:\r
52 return False\r
53 return True\r
54\r
55def _ValidateToken(Token):\r
56 Token = Token.strip()\r
57 Index = Token.find("\"")\r
58 if Index != -1:\r
59 return IsValidBareCString(Token[Index+1:-1])\r
60 return True\r
61\r
62## _ExprError\r
63#\r
64# @param Exception: Exception\r
65#\r
66class _ExprError(Exception):\r
67 def __init__(self, Error = ''):\r
68 Exception.__init__(self)\r
69 self.Error = Error\r
70\r
71## _ExprBase\r
72#\r
73class _ExprBase:\r
74 HEX_PATTERN = '[\t\s]*0[xX][a-fA-F0-9]+'\r
75 INT_PATTERN = '[\t\s]*[0-9]+'\r
76 MACRO_PATTERN = '[\t\s]*\$\(([A-Z][_A-Z0-9]*)\)'\r
77 PCD_PATTERN = \\r
78 '[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*[\t\s]*\.[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*'\r
79 QUOTED_PATTERN = '[\t\s]*L?"[^"]*"'\r
80 BOOL_PATTERN = '[\t\s]*(true|True|TRUE|false|False|FALSE)'\r
81 def __init__(self, Token):\r
82 self.Token = Token\r
83 self.Index = 0\r
84 self.Len = len(Token)\r
85 \r
86 ## SkipWhitespace\r
87 #\r
88 def SkipWhitespace(self):\r
89 for Char in self.Token[self.Index:]:\r
90 if Char not in ' \t':\r
91 break\r
92 self.Index += 1\r
93 \r
94 ## IsCurrentOp\r
95 #\r
f51461c8 96 # @param OpList: option list \r
4234283c
LG
97 # \r
98 def IsCurrentOp(self, OpList):\r
99 self.SkipWhitespace()\r
100 LetterOp = ["EQ", "NE", "GE", "LE", "GT", "LT", "NOT", "and", "AND", \r
101 "or", "OR", "XOR"]\r
102 OpMap = {\r
103 '|' : '|',\r
104 '&' : '&',\r
105 '!' : '=',\r
106 '>' : '=',\r
107 '<' : '='\r
108 }\r
421ccda3 109 \r
4234283c
LG
110 for Operator in OpList:\r
111 if not self.Token[self.Index:].startswith(Operator):\r
112 continue\r
421ccda3 113 \r
4234283c
LG
114 self.Index += len(Operator)\r
115 Char = self.Token[self.Index : self.Index + 1]\r
421ccda3 116\r
4234283c
LG
117 if (Operator in LetterOp and (Char == '_' or Char.isalnum())) \\r
118 or (Operator in OpMap and OpMap[Operator] == Char):\r
119 self.Index -= len(Operator)\r
120 break\r
421ccda3 121 \r
4234283c 122 return True\r
421ccda3 123 \r
4234283c
LG
124 return False\r
125\r
126## _LogicalExpressionParser\r
127#\r
128# @param _ExprBase: _ExprBase object\r
129# \r
130class _LogicalExpressionParser(_ExprBase):\r
131 #\r
132 # STRINGITEM can only be logical field according to spec\r
133 #\r
134 STRINGITEM = -1\r
135 \r
136 #\r
137 # Evaluate to True or False\r
138 #\r
139 LOGICAL = 0\r
140 REALLOGICAL = 2\r
141 \r
142 #\r
143 # Just arithmetic expression\r
144 #\r
145 ARITH = 1\r
146 \r
147 def __init__(self, Token):\r
148 _ExprBase.__init__(self, Token)\r
149 self.Parens = 0\r
150 \r
151 def _CheckToken(self, MatchList):\r
152 for Match in MatchList:\r
153 if Match and Match.start() == 0:\r
154 if not _ValidateToken(\r
155 self.Token[self.Index:self.Index+Match.end()]\r
156 ):\r
157 return False\r
158 \r
159 self.Index += Match.end()\r
160 if self.Token[self.Index - 1] == '"':\r
161 return True\r
162 if self.Token[self.Index:self.Index+1] == '_' or \\r
163 self.Token[self.Index:self.Index+1].isalnum():\r
164 self.Index -= Match.end()\r
165 return False\r
166 \r
167 Token = self.Token[self.Index - Match.end():self.Index]\r
168 if Token.strip() in ["EQ", "NE", "GE", "LE", "GT", "LT",\r
169 "NOT", "and", "AND", "or", "OR", "XOR"]:\r
170 self.Index -= Match.end()\r
171 return False\r
172 \r
173 return True\r
421ccda3 174 \r
4234283c
LG
175 return False\r
176 \r
177 def IsAtomicNumVal(self):\r
178 #\r
179 # Hex number\r
180 #\r
181 Match1 = re.compile(self.HEX_PATTERN).match(self.Token[self.Index:])\r
182 \r
183 #\r
184 # Number\r
185 #\r
186 Match2 = re.compile(self.INT_PATTERN).match(self.Token[self.Index:])\r
187 \r
188 #\r
189 # Macro\r
190 #\r
191 Match3 = re.compile(self.MACRO_PATTERN).match(self.Token[self.Index:])\r
192 \r
193 #\r
194 # PcdName\r
195 #\r
196 Match4 = re.compile(self.PCD_PATTERN).match(self.Token[self.Index:])\r
197 \r
198 return self._CheckToken([Match1, Match2, Match3, Match4])\r
199 \r
200\r
201 def IsAtomicItem(self):\r
202 #\r
203 # Macro\r
204 #\r
205 Match1 = re.compile(self.MACRO_PATTERN).match(self.Token[self.Index:])\r
206 \r
207 #\r
208 # PcdName\r
209 #\r
210 Match2 = re.compile(self.PCD_PATTERN).match(self.Token[self.Index:])\r
211 \r
212 #\r
213 # Quoted string\r
214 #\r
215 Match3 = re.compile(self.QUOTED_PATTERN).\\r
216 match(self.Token[self.Index:].replace('\\\\', '//').\\r
217 replace('\\\"', '\\\''))\r
218 \r
219 return self._CheckToken([Match1, Match2, Match3])\r
220 \r
221 ## A || B\r
222 #\r
223 def LogicalExpression(self):\r
224 Ret = self.SpecNot()\r
421ccda3 225 while self.IsCurrentOp(['||', 'OR', 'or', '&&', 'AND', 'and', 'XOR', 'xor', '^']):\r
4234283c 226 if self.Token[self.Index-1] == '|' and self.Parens <= 0:\r
421ccda3
HC
227 raise _ExprError(ST.ERR_EXPR_OR % self.Token)\r
228 if Ret not in [self.ARITH, self.LOGICAL, self.REALLOGICAL, self.STRINGITEM]:\r
4234283c
LG
229 raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)\r
230 Ret = self.SpecNot()\r
421ccda3 231 if Ret not in [self.ARITH, self.LOGICAL, self.REALLOGICAL, self.STRINGITEM]:\r
4234283c
LG
232 raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)\r
233 Ret = self.REALLOGICAL\r
234 return Ret\r
235 \r
236 def SpecNot(self):\r
421ccda3 237 if self.IsCurrentOp(["NOT", "!", "not"]):\r
4234283c
LG
238 return self.SpecNot()\r
239 return self.Rel()\r
240 \r
421ccda3 241 ## A < B, A > B, A <= B, A >= B\r
4234283c
LG
242 #\r
243 def Rel(self):\r
244 Ret = self.Expr()\r
245 if self.IsCurrentOp(["<=", ">=", ">", "<", "GT", "LT", "GE", "LE",\r
246 "==", "EQ", "!=", "NE"]):\r
421ccda3 247 if Ret == self.STRINGITEM:\r
4234283c
LG
248 raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)\r
249 Ret = self.Expr()\r
421ccda3 250 if Ret == self.REALLOGICAL:\r
4234283c
LG
251 raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)\r
252 Ret = self.REALLOGICAL\r
253 return Ret\r
254 \r
255 ## A + B, A - B\r
256 #\r
257 def Expr(self):\r
258 Ret = self.Factor()\r
421ccda3 259 while self.IsCurrentOp(["+", "-", "&", "|", "^", "XOR", "xor"]):\r
4234283c
LG
260 if self.Token[self.Index-1] == '|' and self.Parens <= 0:\r
261 raise _ExprError(ST.ERR_EXPR_OR)\r
262 if Ret == self.STRINGITEM or Ret == self.REALLOGICAL:\r
263 raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)\r
264 Ret = self.Factor()\r
265 if Ret == self.STRINGITEM or Ret == self.REALLOGICAL:\r
266 raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)\r
267 Ret = self.ARITH\r
268 return Ret\r
269\r
270 ## Factor\r
271 # \r
272 def Factor(self):\r
273 if self.IsCurrentOp(["("]):\r
274 self.Parens += 1\r
275 Ret = self.LogicalExpression()\r
276 if not self.IsCurrentOp([")"]):\r
277 raise _ExprError(ST.ERR_EXPR_RIGHT_PAREN % \\r
278 (self.Token, self.Token[self.Index:]))\r
279 self.Parens -= 1\r
280 return Ret\r
281 \r
282 if self.IsAtomicItem():\r
283 if self.Token[self.Index - 1] == '"':\r
284 return self.STRINGITEM\r
285 return self.LOGICAL\r
286 elif self.IsAtomicNumVal():\r
287 return self.ARITH\r
288 else:\r
289 raise _ExprError(ST.ERR_EXPR_FACTOR % \\r
421ccda3 290 (self.Token[self.Index:], self.Token))\r
4234283c
LG
291 \r
292 ## IsValidLogicalExpression\r
293 #\r
294 def IsValidLogicalExpression(self):\r
295 if self.Len == 0:\r
421ccda3 296 return False, ST.ERR_EXPRESS_EMPTY\r
4234283c 297 try:\r
421ccda3 298 if self.LogicalExpression() not in [self.ARITH, self.LOGICAL, self.REALLOGICAL, self.STRINGITEM]:\r
4234283c 299 return False, ST.ERR_EXPR_LOGICAL % self.Token\r
5b0671c1 300 except _ExprError as XExcept:\r
4234283c
LG
301 return False, XExcept.Error\r
302 self.SkipWhitespace()\r
303 if self.Index != self.Len:\r
304 return False, (ST.ERR_EXPR_BOOLEAN % \\r
305 (self.Token[self.Index:], self.Token))\r
306 return True, ''\r
307\r
308## _ValidRangeExpressionParser\r
309#\r
310class _ValidRangeExpressionParser(_ExprBase):\r
311 INT_RANGE_PATTERN = '[\t\s]*[0-9]+[\t\s]*-[\t\s]*[0-9]+'\r
312 HEX_RANGE_PATTERN = \\r
313 '[\t\s]*0[xX][a-fA-F0-9]+[\t\s]*-[\t\s]*0[xX][a-fA-F0-9]+'\r
314 def __init__(self, Token):\r
315 _ExprBase.__init__(self, Token)\r
421ccda3
HC
316 self.Parens = 0\r
317 self.HEX = 1\r
318 self.INT = 2\r
319 self.IsParenHappen = False\r
320 self.IsLogicalOpHappen = False\r
4234283c
LG
321 \r
322 ## IsValidRangeExpression\r
323 #\r
324 def IsValidRangeExpression(self):\r
325 if self.Len == 0:\r
421ccda3 326 return False, ST.ERR_EXPR_RANGE_EMPTY\r
4234283c 327 try:\r
421ccda3
HC
328 if self.RangeExpression() not in [self.HEX, self.INT]:\r
329 return False, ST.ERR_EXPR_RANGE % self.Token\r
5b0671c1 330 except _ExprError as XExcept:\r
421ccda3
HC
331 return False, XExcept.Error\r
332 \r
4234283c
LG
333 self.SkipWhitespace()\r
334 if self.Index != self.Len:\r
421ccda3
HC
335 return False, (ST.ERR_EXPR_RANGE % self.Token)\r
336 return True, ''\r
4234283c
LG
337 \r
338 ## RangeExpression\r
339 #\r
340 def RangeExpression(self):\r
421ccda3
HC
341 Ret = self.Unary()\r
342 while self.IsCurrentOp(['OR', 'AND', 'and', 'or']):\r
343 self.IsLogicalOpHappen = True\r
344 if not self.IsParenHappen:\r
345 raise _ExprError(ST.ERR_PAREN_NOT_USED % self.Token)\r
346 self.IsParenHappen = False\r
347 Ret = self.Unary()\r
348 \r
349 if self.IsCurrentOp(['XOR']):\r
350 Ret = self.Unary()\r
351 \r
352 return Ret\r
4234283c
LG
353 \r
354 ## Unary\r
355 #\r
356 def Unary(self):\r
421ccda3 357 if self.IsCurrentOp(["NOT"]):\r
4234283c 358 return self.Unary()\r
421ccda3 359 \r
4234283c
LG
360 return self.ValidRange()\r
361 \r
362 ## ValidRange\r
363 # \r
364 def ValidRange(self):\r
421ccda3 365 Ret = -1\r
4234283c 366 if self.IsCurrentOp(["("]):\r
421ccda3
HC
367 self.IsLogicalOpHappen = False\r
368 self.IsParenHappen = True\r
369 self.Parens += 1\r
370 if self.Parens > 1:\r
371 raise _ExprError(ST.ERR_EXPR_RANGE_DOUBLE_PAREN_NESTED % self.Token)\r
372 Ret = self.RangeExpression()\r
4234283c 373 if not self.IsCurrentOp([")"]):\r
421ccda3
HC
374 raise _ExprError(ST.ERR_EXPR_RIGHT_PAREN % self.Token)\r
375 self.Parens -= 1\r
376 return Ret\r
377 \r
378 if self.IsLogicalOpHappen:\r
379 raise _ExprError(ST.ERR_PAREN_NOT_USED % self.Token)\r
4234283c 380 \r
421ccda3 381 if self.IsCurrentOp(["LT", "GT", "LE", "GE", "EQ", "XOR"]):\r
4234283c
LG
382 IntMatch = \\r
383 re.compile(self.INT_PATTERN).match(self.Token[self.Index:])\r
384 HexMatch = \\r
385 re.compile(self.HEX_PATTERN).match(self.Token[self.Index:])\r
386 if HexMatch and HexMatch.start() == 0:\r
387 self.Index += HexMatch.end()\r
421ccda3 388 Ret = self.HEX\r
4234283c
LG
389 elif IntMatch and IntMatch.start() == 0:\r
390 self.Index += IntMatch.end()\r
421ccda3 391 Ret = self.INT\r
4234283c 392 else:\r
421ccda3 393 raise _ExprError(ST.ERR_EXPR_RANGE_FACTOR % (self.Token[self.Index:], self.Token))\r
4234283c
LG
394 else:\r
395 IntRangeMatch = re.compile(\r
396 self.INT_RANGE_PATTERN).match(self.Token[self.Index:]\r
397 )\r
398 HexRangeMatch = re.compile(\r
399 self.HEX_RANGE_PATTERN).match(self.Token[self.Index:]\r
400 )\r
401 if HexRangeMatch and HexRangeMatch.start() == 0:\r
402 self.Index += HexRangeMatch.end()\r
421ccda3 403 Ret = self.HEX\r
4234283c
LG
404 elif IntRangeMatch and IntRangeMatch.start() == 0:\r
405 self.Index += IntRangeMatch.end()\r
421ccda3 406 Ret = self.INT\r
4234283c 407 else:\r
421ccda3
HC
408 raise _ExprError(ST.ERR_EXPR_RANGE % self.Token)\r
409\r
410 return Ret\r
411\r
412## _ValidListExpressionParser\r
413#\r
414class _ValidListExpressionParser(_ExprBase):\r
415 VALID_LIST_PATTERN = '(0[xX][0-9a-fA-F]+|[0-9]+)([\t\s]*,[\t\s]*(0[xX][0-9a-fA-F]+|[0-9]+))*'\r
416 def __init__(self, Token):\r
417 _ExprBase.__init__(self, Token)\r
418 self.NUM = 1\r
4234283c 419 \r
421ccda3
HC
420 def IsValidListExpression(self):\r
421 if self.Len == 0:\r
422 return False, ST.ERR_EXPR_LIST_EMPTY\r
423 try:\r
424 if self.ListExpression() not in [self.NUM]:\r
425 return False, ST.ERR_EXPR_LIST % self.Token\r
5b0671c1 426 except _ExprError as XExcept:\r
421ccda3 427 return False, XExcept.Error\r
4234283c 428\r
421ccda3
HC
429 self.SkipWhitespace()\r
430 if self.Index != self.Len:\r
431 return False, (ST.ERR_EXPR_LIST % self.Token)\r
432\r
433 return True, ''\r
434 \r
435 def ListExpression(self):\r
436 Ret = -1\r
437 self.SkipWhitespace()\r
438 ListMatch = re.compile(self.VALID_LIST_PATTERN).match(self.Token[self.Index:])\r
439 if ListMatch and ListMatch.start() == 0:\r
440 self.Index += ListMatch.end()\r
441 Ret = self.NUM\r
442 else:\r
443 raise _ExprError(ST.ERR_EXPR_LIST % self.Token)\r
444\r
445 return Ret\r
446 \r
4234283c
LG
447## _StringTestParser\r
448#\r
449class _StringTestParser(_ExprBase):\r
450 def __init__(self, Token):\r
451 _ExprBase.__init__(self, Token)\r
452\r
453 ## IsValidStringTest\r
454 # \r
455 def IsValidStringTest(self):\r
456 if self.Len == 0:\r
457 return False, ST.ERR_EXPR_EMPTY\r
458 try:\r
459 self.StringTest()\r
5b0671c1 460 except _ExprError as XExcept:\r
4234283c
LG
461 return False, XExcept.Error\r
462 return True, ''\r
463\r
464 ## StringItem\r
465 # \r
466 def StringItem(self):\r
467 Match1 = re.compile(self.QUOTED_PATTERN)\\r
468 .match(self.Token[self.Index:].replace('\\\\', '//')\\r
469 .replace('\\\"', '\\\''))\r
470 Match2 = re.compile(self.MACRO_PATTERN).match(self.Token[self.Index:])\r
471 Match3 = re.compile(self.PCD_PATTERN).match(self.Token[self.Index:])\r
472 MatchList = [Match1, Match2, Match3]\r
473 for Match in MatchList:\r
474 if Match and Match.start() == 0:\r
475 if not _ValidateToken(\r
476 self.Token[self.Index:self.Index+Match.end()]\r
477 ):\r
478 raise _ExprError(ST.ERR_EXPR_STRING_ITEM % \\r
479 (self.Token, self.Token[self.Index:]))\r
480 self.Index += Match.end()\r
481 Token = self.Token[self.Index - Match.end():self.Index]\r
482 if Token.strip() in ["EQ", "NE"]:\r
483 raise _ExprError(ST.ERR_EXPR_STRING_ITEM % \\r
484 (self.Token, self.Token[self.Index:]))\r
485 return\r
486 else:\r
487 raise _ExprError(ST.ERR_EXPR_STRING_ITEM % \\r
488 (self.Token, self.Token[self.Index:]))\r
489\r
490 ## StringTest\r
491 # \r
492 def StringTest(self):\r
493 self.StringItem()\r
494 if not self.IsCurrentOp(["==", "EQ", "!=", "NE"]):\r
495 raise _ExprError(ST.ERR_EXPR_EQUALITY % \\r
421ccda3 496 (self.Token[self.Index:], self.Token))\r
4234283c
LG
497 self.StringItem()\r
498 if self.Index != self.Len:\r
499 raise _ExprError(ST.ERR_EXPR_BOOLEAN % \\r
500 (self.Token[self.Index:], self.Token))\r
501\r
502##\r
421ccda3 503# Check syntax of string test\r
4234283c 504#\r
421ccda3 505# @param Token: string test token\r
4234283c 506#\r
421ccda3 507def IsValidStringTest(Token, Flag=False):\r
4234283c
LG
508 #\r
509 # Not do the check right now, keep the implementation for future enhancement.\r
510 #\r
511 if not Flag:\r
512 return True, ""\r
421ccda3
HC
513 return _StringTestParser(Token).IsValidStringTest()\r
514\r
4234283c
LG
515\r
516##\r
421ccda3 517# Check syntax of logical expression\r
4234283c 518#\r
421ccda3 519# @param Token: expression token\r
4234283c 520#\r
421ccda3 521def IsValidLogicalExpr(Token, Flag=False):\r
4234283c
LG
522 #\r
523 # Not do the check right now, keep the implementation for future enhancement.\r
524 #\r
525 if not Flag:\r
526 return True, ""\r
421ccda3 527 return _LogicalExpressionParser(Token).IsValidLogicalExpression()\r
4234283c
LG
528\r
529##\r
530# Check syntax of range expression\r
531#\r
532# @param Token: range expression token\r
533#\r
534def IsValidRangeExpr(Token):\r
535 return _ValidRangeExpressionParser(Token).IsValidRangeExpression()\r
536\r
421ccda3
HC
537##\r
538# Check syntax of value list expression token\r
539#\r
540# @param Token: value list expression token \r
541#\r
542def IsValidListExpr(Token):\r
543 return _ValidListExpressionParser(Token).IsValidListExpression()\r
544\r
4234283c
LG
545##\r
546# Check whether the feature flag expression is valid or not\r
547#\r
548# @param Token: feature flag expression\r
549#\r
550def IsValidFeatureFlagExp(Token, Flag=False):\r
551 #\r
552 # Not do the check right now, keep the implementation for future enhancement.\r
553 #\r
554 if not Flag:\r
555 return True, "", Token\r
556 else:\r
557 if Token in ['TRUE', 'FALSE', 'true', 'false', 'True', 'False',\r
558 '0x1', '0x01', '0x0', '0x00']:\r
559 return True, ""\r
560 Valid, Cause = IsValidStringTest(Token, Flag)\r
561 if not Valid:\r
562 Valid, Cause = IsValidLogicalExpr(Token, Flag)\r
563 if not Valid:\r
564 return False, Cause \r
565 return True, ""\r
566\r
567if __name__ == '__main__':\r
421ccda3
HC
568# print IsValidRangeExpr('LT 9')\r
569 print _LogicalExpressionParser('gCrownBayTokenSpaceGuid.PcdPciDevice1BridgeAddressLE0').IsValidLogicalExpression()\r
570\r
571\r
572 \r