我正在使用一个可以在Scilab的自定义版本中生成“场景”文件的专有驾驶模拟器。我提供了一个单一的11,000行长的“主”文件,由此我需要替换某些值以生成该场景的版本n版本。在自定义语法中修改变量的最有效方法?
的语法为单亲TASK
的最小的例子是这样的:
TYPEOF TASK (57)
{
LABEL="Dot 3a"/*replace with name for name in list */
TASK_KIND="0"
TYPEOF VARIABLE (53)
{
LABEL="Time1"
TYPE="FLOAT"
VALUE="14.000000" /* replace with random.integer() */
INTERACTIVE="VOID"
TYPEOF VARIABLE (54)
{
LABEL="X_pos1"
TYPE="FLOAT"
VALUE="23.600000"
INTERACTIVE="VOID"
TYPEOF TASK (58)
{
LABEL="Task: ISI"
TASK_KIND="0"
TYPEOF RULE (115)
{
LABEL="Rule: Go to subtask after Time1 seconds"
TYPEOF CONDITION (SUPERIOR)
{
IS_EXPANDED="1"
MODIFIER="BECOMES_TRUE"
TYPEOF PARAMETER (OPERAND_1)
{
KIND="FUNCTION"
TYPEOF FUNCTION (GET_TASK_CLOCK)
{
}
OWNER_FILE=""
}
TYPEOF PARAMETER (OPERAND_2)
{
KIND="VARIABLE"
VALUE="53"
OWNER_FILE=""
}
}
TYPEOF ACTION (GOTO_TASK)
{
IS_EXPANDED="1"
TYPEOF PARAMETER (TASK_NUMBER)
{
KIND="ENUM"
VALUE="GOTO_NEXT_TASK"
OWNER_FILE=""
}
}
}
}
我需要在这个脚本标准输入来代替某些价值观。例如,在父级TASK
下有一个名称将取代LABEL
的值的列表;并与我的第一个解决方案基于Python的正则表达式6和
16之间的随机数,以取代VALUE
的第一个父VARIABLE
,类似如下(但每个值我寻求改变):
for row in scenarioInput:
parenttaskmatch = re.search("^\t\tTYPEOF TASK",row)
if parenttaskmatch:
replacementrow = re.sub(r"([0-9]{1,3})",repl,row)
有人建议我可以用Parsimonious之类的东西编写一个自定义语法,然后用胡子重新生成输出。
from parsimonious.grammar import Grammar
grammar = Grammar(r"""
any = task/data
task = "TYPEOF " key " (" number ")" newline open_curly any+ close_curly
data = key "=" quote text quote newline
open_curly = "{" newline
close_curly = "}" newline
key = ~"[A-Z 0-9_]*"
text = ~"[A-Z0-9 ]*"i
number = ~"[0-9]*"
newline = "\n"
space = " "
quote = "\""
""")
text = open('example_driving_rule.sci').read()
grammar.parse(text)
# Note doesn't work
正如你所看到的,这不是一个有效的解决方案。你们认为什么是更好的解决方案?
你可能确实想要一个真正的解析器。正则表达式很难保证他们会处理正确的事情,如果你有引号字符串之类的令人讨厌的东西。我从来没有听说过Parsimonious,但它看起来是一个开始的好地方!为什么它不工作? –