SCons 中错误的 D 依赖逻辑
Faulty D Dependency Logic in SCons
我在 SCons 中找到了 D 源的依赖逻辑中的错误。
self.cre
regexp import\s+(?:\[a-zA-Z0-9_.\]+)\s*(?:,\s*(?:\[a-zA-Z0-9_.\]+)\s*)*;
in SCons.Scanner.D
不包括诸如...
之类的模式
import IMPORT_PATH : SYMBOL;
...仅:
import IMPORT_PATH;
与self.cre2
regexp (?:import\s)?\s*([a-zA-Z0-9_.]+)\s*(?:,|;)
two lines later相同。
我认为 self.cre
和 self.cre2
正则表达式都需要修复;但我不太明白它们之间的关系。我的猜测是 self.cre
匹配整个导入语句,而 self.cre2
匹配其中的一部分。我对么?如果是这样,需要更正 self.cre2
以处理以下情况:
import X, Y, Z;
有谁知道如何修复正则表达式以便处理这些情况?
我的第一个尝试是改变
p = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)\s*)*;'
至
p = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)(?:\s*:\s*[a-zA-Z0-9_.]+)??\s*)*;'
我试过对此进行调试,但没有成功。
Python:
import re
p = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)\s*)*;'
re.match(p, "import first;") # match
re.match(p, "import first : f;") # no match
p2 = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)(?:\s*:\s*[a-zA-Z0-9_.]+)??\s*)*;'
re.match(p2, "import first;") # match
re.match(p2, "import first : f;") # no match but should match
re.match(p2, "import first : f, second : g;") # no match but should match
简答
要处理您列出的所有情况,请尝试对 (self.cre
) 模式进行以下更改:
import\s+(?:[a-zA-Z0-9_.]+)\s*(?:(?:\s+:\s+[a-zA-Z0-9_.]+\s*)?(?:,\s*(?:[a-zA-Z0-9_.]+)(?:\s*:\s*[a-zA-Z0-9_.]+)??\s*)*)*;
深入挖掘
self.cre 对比 self.cre2
是的,find_include_names
方法...
def find_include_names(self, node):
includes = []
for i in self.cre.findall(node.get_text_contents()):
includes = includes + self.cre2.findall(i)
return includes
...证实了你猜想的self.cre
和self.cre2
之间的关系:前者匹配整个导入语句,后者匹配(并捕获)其中的模块。 (注意中间 (
...)
capture 组 self.cre2
与 (?:
...)
非-在 self.cre
和 self.cre2
的其他地方捕获组。)
self.cre
正在取货where your Python snippet left off...
import re
import1 = "import first;"
import2 = "import first : f;"
import3 = "import first : f, second : g;"
p = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)\s*)*;'
pm1 = re.match(p, import1) # match
if pm1 != None:
print "p w/ import1 => " + pm1.group(0)
pm2 = re.match(p, import2) # no match
if pm2 != None:
print "p w/ import2 => " + pm2.group(0)
p2 = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)(?:\s*:\s*[a-zA-Z0-9_.]+)??\s*)*;'
p2m1 = re.match(p2, import1) # match
if p2m1 != None:
print "p2 w/ import1 => " + p2m1.group(0)
p2m2 = re.match(p2, import2) # no match but should match
if p2m2 != None:
print "p2 w/ import2 => " + p2m2.group(0)
p2m3 = re.match(p2, import3) # no match but should match
if p2m3 != None:
print "p2 w/ import3 => " + p2m3.group(0)
...,我们得到以下 p
和 p2
尝试匹配导入语句的预期输出:
p w/ import1 => import first;
p2 w/ import1 => import first;
现在考虑p2prime
,其中我在上面做了changes to arrive at the pattern I suggested:
import re
import1 = "import first;"
import2 = "import first : f;"
import3 = "import first : f, second : g;"
import4 = "import first, second, third;"
p2prime = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:(?:\s+:\s+[a-zA-Z0-9_.]+\s*)?(?:,\s*(?:[a-zA-Z0-9_.]+)(?:\s*:\s*[a-zA-Z0-9_.]+)??\s*)*)*;'
p2pm1 = re.match(p2prime, import1) # match
if p2pm1 != None:
print "p2prime w/ import1 => " + p2pm1.group(0)
p2pm2 = re.match(p2prime, import2) # now a match
if p2pm2 != None:
print "p2prime w/ import2 => " + p2pm2.group(0)
p2pm3 = re.match(p2prime, import3) # now a match
if p2pm3 != None:
print "p2prime w/ import3 => " + p2pm3.group(0)
p2pm4 = re.match(p2prime, import4) # now a match
if p2pm4 != None:
print "p2prime w/ import4 => " + p2pm4.group(0)
使用更新后的模式 (p2prime
),我们得到以下期望的输出,因为它尝试匹配导入语句:
p2prime w/ import1 => import first;
p2prime w/ import2 => import first : f;
p2prime w/ import3 => import first : f, second : g;
p2prime w/ import4 => import first, second, third;
这是一个相当冗长且复杂的模式:因此,如果有机会进一步微调它,我不会感到惊讶;但它可以满足您的需求,应该为微调提供坚实的基础。
self.cre2
对于 self.cre2
,类似地尝试以下模式:
(?:import\s)?\s*(?:([a-zA-Z0-9_.]+)(?:\s+:\s+[a-zA-Z0-9_.]+\s*)?)\s*(?:,|;)
但是请记住,因为 D's <module> : <symbol>
selective imports 只是 - 选择性,在选择性导入中捕获模块名称可能不是您最终需要的(例如,与捕获模块和选定的符号名称相比) ).正如我对我建议的 self.cre
正则表达式的类似解释,在必要的地方进一步微调应该不难。
我在 SCons 中找到了 D 源的依赖逻辑中的错误。
self.cre
regexp import\s+(?:\[a-zA-Z0-9_.\]+)\s*(?:,\s*(?:\[a-zA-Z0-9_.\]+)\s*)*;
in SCons.Scanner.D
不包括诸如...
import IMPORT_PATH : SYMBOL;
...仅:
import IMPORT_PATH;
与self.cre2
regexp (?:import\s)?\s*([a-zA-Z0-9_.]+)\s*(?:,|;)
two lines later相同。
我认为 self.cre
和 self.cre2
正则表达式都需要修复;但我不太明白它们之间的关系。我的猜测是 self.cre
匹配整个导入语句,而 self.cre2
匹配其中的一部分。我对么?如果是这样,需要更正 self.cre2
以处理以下情况:
import X, Y, Z;
有谁知道如何修复正则表达式以便处理这些情况?
我的第一个尝试是改变
p = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)\s*)*;'
至
p = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)(?:\s*:\s*[a-zA-Z0-9_.]+)??\s*)*;'
我试过对此进行调试,但没有成功。
Python:
import re
p = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)\s*)*;'
re.match(p, "import first;") # match
re.match(p, "import first : f;") # no match
p2 = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)(?:\s*:\s*[a-zA-Z0-9_.]+)??\s*)*;'
re.match(p2, "import first;") # match
re.match(p2, "import first : f;") # no match but should match
re.match(p2, "import first : f, second : g;") # no match but should match
简答
要处理您列出的所有情况,请尝试对 (self.cre
) 模式进行以下更改:
import\s+(?:[a-zA-Z0-9_.]+)\s*(?:(?:\s+:\s+[a-zA-Z0-9_.]+\s*)?(?:,\s*(?:[a-zA-Z0-9_.]+)(?:\s*:\s*[a-zA-Z0-9_.]+)??\s*)*)*;
深入挖掘
self.cre 对比 self.cre2
是的,find_include_names
方法...
def find_include_names(self, node):
includes = []
for i in self.cre.findall(node.get_text_contents()):
includes = includes + self.cre2.findall(i)
return includes
...证实了你猜想的self.cre
和self.cre2
之间的关系:前者匹配整个导入语句,后者匹配(并捕获)其中的模块。 (注意中间 (
...)
capture 组 self.cre2
与 (?:
...)
非-在 self.cre
和 self.cre2
的其他地方捕获组。)
self.cre
正在取货where your Python snippet left off...
import re
import1 = "import first;"
import2 = "import first : f;"
import3 = "import first : f, second : g;"
p = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)\s*)*;'
pm1 = re.match(p, import1) # match
if pm1 != None:
print "p w/ import1 => " + pm1.group(0)
pm2 = re.match(p, import2) # no match
if pm2 != None:
print "p w/ import2 => " + pm2.group(0)
p2 = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)(?:\s*:\s*[a-zA-Z0-9_.]+)??\s*)*;'
p2m1 = re.match(p2, import1) # match
if p2m1 != None:
print "p2 w/ import1 => " + p2m1.group(0)
p2m2 = re.match(p2, import2) # no match but should match
if p2m2 != None:
print "p2 w/ import2 => " + p2m2.group(0)
p2m3 = re.match(p2, import3) # no match but should match
if p2m3 != None:
print "p2 w/ import3 => " + p2m3.group(0)
...,我们得到以下 p
和 p2
尝试匹配导入语句的预期输出:
p w/ import1 => import first;
p2 w/ import1 => import first;
现在考虑p2prime
,其中我在上面做了changes to arrive at the pattern I suggested:
import re
import1 = "import first;"
import2 = "import first : f;"
import3 = "import first : f, second : g;"
import4 = "import first, second, third;"
p2prime = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:(?:\s+:\s+[a-zA-Z0-9_.]+\s*)?(?:,\s*(?:[a-zA-Z0-9_.]+)(?:\s*:\s*[a-zA-Z0-9_.]+)??\s*)*)*;'
p2pm1 = re.match(p2prime, import1) # match
if p2pm1 != None:
print "p2prime w/ import1 => " + p2pm1.group(0)
p2pm2 = re.match(p2prime, import2) # now a match
if p2pm2 != None:
print "p2prime w/ import2 => " + p2pm2.group(0)
p2pm3 = re.match(p2prime, import3) # now a match
if p2pm3 != None:
print "p2prime w/ import3 => " + p2pm3.group(0)
p2pm4 = re.match(p2prime, import4) # now a match
if p2pm4 != None:
print "p2prime w/ import4 => " + p2pm4.group(0)
使用更新后的模式 (p2prime
),我们得到以下期望的输出,因为它尝试匹配导入语句:
p2prime w/ import1 => import first;
p2prime w/ import2 => import first : f;
p2prime w/ import3 => import first : f, second : g;
p2prime w/ import4 => import first, second, third;
这是一个相当冗长且复杂的模式:因此,如果有机会进一步微调它,我不会感到惊讶;但它可以满足您的需求,应该为微调提供坚实的基础。
self.cre2
对于 self.cre2
,类似地尝试以下模式:
(?:import\s)?\s*(?:([a-zA-Z0-9_.]+)(?:\s+:\s+[a-zA-Z0-9_.]+\s*)?)\s*(?:,|;)
但是请记住,因为 D's <module> : <symbol>
selective imports 只是 - 选择性,在选择性导入中捕获模块名称可能不是您最终需要的(例如,与捕获模块和选定的符号名称相比) ).正如我对我建议的 self.cre
正则表达式的类似解释,在必要的地方进一步微调应该不难。