SeS: Having scrolled through -I guess- most examples regarding syntax highlighting in this wiki, I was not able to get out definitive solution for implementing a procedure for syntax checks in tG²...the most satisfying way. Also, I needed to know the mechanics of syntax checks in depth, best way for me is to work the bottom-up way, I figured.
What I did understand so far is the most basic checks that are required as a minimum, are related with braces, such as {}, and (). While some solutions also dive into checking quote balancing as well. What I also learned is the existance of command "info complete {}". So, I relied upon my previous knowledge of finding balanced braces for regular (c)text highlighting and figured out a way to combine it with "info complete {}" to provide a first generation basic syntax lighlighting procedure for tG². With time, I hope to get better insight and improve the algorithm. Satisfied with the intermediate results though.
How it works: I simply scan each line for each category of brace types and manage a counter for the occurrence of opening/closing braces (i & j). While this method will also register braces inside comments, which it ideally should not... This is where "info complete {}" comes in handy. So long as this latter command does not fail, I will simply not report eventual inbalances found. If the command fails on the other hand, I can provide the first line (z) where the inbalance starts. I noticed it is effective in 50~75% of cases, which is better than nothing in tG²'s current version v1.07.01 - beta6. With some additional code to the check4syntax procedure, tG² is lately able to jump to the line in the source editor and highlight it for further analyses by the user.
Current script does not perform a run-time like syntax check either, so most inbalances within procedure bodies will be discovered by wishrun.exe only...BUT...the tG² release that I am working on as of this writing @ 15th Oct 2014, is able to detect background error states of the tool being run and pinppoint the line of concern in the source code! Thanks to a simple handshaking mechanism between tG² and the tool. So, this is partially covered at the moment. Feature is optional btw, if we prefer the good old Tk-dialog to view the bgerror and wonder where to go now, we still have the choice...
Further things to be improved:
- not able to accurately pinpoint the exact position/character causing the syntax error - Success rate of accurately pinpointing the probable line causing the error is ~50..75% - no checks for quote balancing...yet - braces inside comments are registered as well, ideally should not...
I think I got myself a nice simple piece of 1st generation code to chew on for the coming months...anyway, here it is:
proc openFile file { set f [open $file] set content [read $f] close $f return $content } proc check4syntax files { set allFiles $files foreach file $allFiles { set data [openFile $file] if {![info complete $data]} {set found([file tail $file]) " : unknown"} {set found([file tail $file]) {}} set data [split $data \n] foreach pats {"\\\{ \\\}" "\\\( \\\)" "\\\[ \\\]"} { set i 0 ;# index for starting brace set j 0 ;# index for ending brace set z 0 ;# line counter set synt($pats) 0 foreach line $data { set pat "[lindex $pats 0]"; set s 0 while {[string first $pat $line $s]>=0} {incr i; set s [expr [string first $pat $line $s]+1]} set pat "\\[lindex $pats 0]"; set s 0 while {[string first $pat $line $s]>=0} {incr i -1; set s [expr [string first $pat $line $s]+1]} set pat "[lindex $pats 1]"; set s 0 while {[string first $pat $line $s]>=0} {incr j; set s [expr [string first $pat $line $s]+1]} set pat "\\[lindex $pats 1]"; set s 0 while {[string first $pat $line $s]>=0} {incr j -1; set s [expr [string first $pat $line $s]+1]} incr z if {($i>$j) && ($synt($pats)==0)} {set synt($pats) $z} { if {($i<=$j) && ($synt($pats)!=0)} {set synt($pats) 0} } } if {$j!=$i} {set found([file tail $file]) "$found([file tail $file]) : $pats @ line $synt($pats)"; break} } } set ret {} foreach file $allFiles { if {($found([file tail $file]) ne {}) && ([lindex $found([file tail $file]) 1] eq {unknown})} { set msg "Syntax check FAILED inside [file tail $file], for the following category $found([file tail $file])" set ret "${ret}[file tail $file] " } { set msg "Syntax check OK for [file tail $file]" } puts $msg } if {$ret ne {}} {puts "Syntax check FAILED for 1 or more files, see logging for more info..." 1; return 1} return 0 }