Parsing 解析器中的换行支持(TCL)
所以,我有一个解析器,用TCL编写。解析文件中有许多命令。现在,我需要添加对换行符的支持。 例如 我有这样的东西Parsing 解析器中的换行支持(TCL),parsing,tcl,Parsing,Tcl,所以,我有一个解析器,用TCL编写。解析文件中有许多命令。现在,我需要添加对换行符的支持。 例如 我有这样的东西 while { ! [eof $currentFileDescriptor] } { set line [gets $currentFileDescriptor] set lst [lindex [regexp -all -inline {^(\s*(\S*)\s*)*(\{(.*)\})?(\s*(\S*)\s*)*$} $line]
while { ! [eof $currentFileDescriptor] } {
set line [gets $currentFileDescriptor]
set lst [lindex [regexp -all -inline {^(\s*(\S*)\s*)*(\{(.*)\})?(\s*(\S*)\s*)*$} $line] 0]
set tok [string toupper [lindex $lst 0]]
switch -glob $tok {
"\#*" { }
"MY_COMMAND_1" { parseMyCommand1 $handler $lst }
.....#other commands }
}
incr lnum
}
我正在寻找一个最佳且有效的解决方案。看起来您已经定义了一种领域特定语言(DSL),并在Tcl中实现了解析。您还可以使用Tcl解析本身来处理行延续和引号处理之类的事情。这样做的方法是创建一个安全的解释器,并且在安全解释器中只提供DSL所需的命令。然后在安全子解释器中解释配置文件。这本书有一些例子 这种方法的优点是解析由普通的Tcl解析器处理。但是,您可以完全控制安全解释器中公开的命令。您还可以控制它可以使用的资源量(堆栈和内存),并限制它对文件系统或网络的可见性 如果您不想进入这个领域,那么您只需要实现反斜杠换行的识别,并缓冲这些行,直到您有一个完整的行。类似以下内容(未经测试):
看起来您已经定义了一种特定于域的语言(DSL),并在Tcl中实现了解析。您还可以使用Tcl解析本身来处理行延续和引号处理之类的事情。这样做的方法是创建一个安全的解释器,并且在安全解释器中只提供DSL所需的命令。然后在安全子解释器中解释配置文件。这本书有一些例子 这种方法的优点是解析由普通的Tcl解析器处理。但是,您可以完全控制安全解释器中公开的命令。您还可以控制它可以使用的资源量(堆栈和内存),并限制它对文件系统或网络的可见性 如果您不想进入这个领域,那么您只需要实现反斜杠换行的识别,并缓冲这些行,直到您有一个完整的行。类似以下内容(未经测试):
请突出你的问题好吗?到目前为止,我看不到任何问题。如果行以反斜杠结尾,请在下一行添加(如果可用)?如果行以反斜杠结尾,请删除反斜杠并将下一行不带反斜杠附加到当前行。重复,直到当前行的最后一个字符是反斜杠。例如,问题中提到的“my_命令”应等同于以下“my_命令arg1 arg2 arg3”您可以突出显示您的问题吗?到目前为止,我看不到任何问题。如果行以反斜杠结尾,请在下一行添加(如果可用)?如果行以反斜杠结尾,请删除反斜杠并将下一行不带反斜杠附加到当前行。重复,直到当前行的最后一个字符是反斜杠。例如,问题中提到的“my_命令”应等同于以下“my_命令arg1 arg2 arg3”谢谢!真的很有帮助:)谢谢!真的很有帮助:)
while { ! [eof $currentFileDescriptor] } {
set line [gets $currentFileDescriptor]
set lst [lindex [regexp -all -inline {^(\s*(\S*)\s*)*(\{(.*)\})?(\s*(\S*)\s*)*$} $line] 0]
set tok [string toupper [lindex $lst 0]]
switch -glob $tok {
"\#*" { }
"MY_COMMAND_1" { parseMyCommand1 $handler $lst }
.....#other commands }
}
incr lnum
}
set linenum 0
set buffer ""
while {[gets $input line] != -1} {
incr linenum
if {[regexp {\\$} $line]} {
append buffer [string range $line 0 end-1]
continue
} else {
append buffer $line
}
ParseCompleteLine $linenum $buffer
set buffer ""
}