Parsing 解析器中的换行支持(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]

所以,我有一个解析器,用TCL编写。解析文件中有许多命令。现在,我需要添加对换行符的支持。 例如

我有这样的东西

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 ""
}