我正在使用一個可以在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,但它看起來是一個開始的好地方!爲什麼它不工作? –