dotfiles

My dotfiles.
Log | Files | Refs | LICENSE

jsf.jsf (16834B)


      1 # JOE Syntax-Highlighting Description
      2 #                 for
      3 # JOE Syntax-Highlighting Descriptions
      4 #
      5 # Author: Charles J. Tabony
      6 # Date:   2007-2-13
      7 #
      8 # This is a highlighting description for files like this one.
      9 #
     10 # When CHECKING is defined, it is very aggressive about error checking.  The
     11 # idea is that anywhere the highlighted file contains a syntax error, at least
     12 # one visible character should be highlighted as Bad.  While that feature is
     13 # useful for finding syntax errors, it is annoying when editing a file, since
     14 # nearly everything is an error until you finish typing it.
     15 #
     16 # In order to not annoy people by default, but keep the option of strictly
     17 # checking syntax, I predicated the stricter checking on the CHECKING parameter. 
     18 # By default, things that are incomplete are generally not marked as errors. 
     19 # Only things that appear to be actual mistakes are highlighted as Bad.  To
     20 # enable the stricter checking, one can highlight the file with the jsf_check
     21 # syntax.  jsf_check.jsf simply calls the entire jsf.jsf file with CHECKING
     22 # defined.
     23 #
     24 # The idea is for authors of a jsf file to edit their file, highlight it with
     25 # jsf_check, and then look for any red characters.  That way they can check for
     26 # syntax errors before testing the changes.
     27 
     28 
     29 
     30 
     31 #####################
     32 # Color Definitions #
     33 #####################
     34 
     35 =Idle
     36 =Comment
     37 =Conditional	+Precond +Preproc
     38 =Parameter	+Ident
     39 =Keyword
     40 =Color		+Type
     41 =ColorRef
     42 =State		+Ident
     43 =Subr		+Ident
     44 =Constant
     45 =Number		+Constant
     46 =String		+Constant
     47 =StringEscape	+Escape +String
     48 =Bad
     49 
     50 
     51 
     52 
     53 ##################
     54 # Initial States #
     55 ##################
     56 
     57 # This is a dummy state that simply jumps to comment_or_bad.  It is here so that
     58 # when this file calls itself with the STRINGS parameter defined, comment_or_bad
     59 # will effectively be the initial state.  comment_or_bad should be the initial
     60 # state because strings and istrings options can only be used as the last option
     61 # of a transition.
     62 .ifdef STRINGS
     63 :strings_initial Idle
     64 	*		comment_or_bad		noeat
     65 .endif
     66 
     67 # Each new line (that is not considered bad from the beginning) begins in the
     68 # idle state.  The first non-whitespace character determines what the rest of
     69 # the line should contain.  Following a strings or istrings option, only strings
     70 # and comments are allowed until the word "done" denotes the end of the list.
     71 :idle Idle
     72 	*		bad			noeat
     73 	" \t\n"		idle
     74 .ifdef STRINGS
     75 .else
     76 	"-"		sync_lines_first
     77 	"."		conditional_first	mark recolor=-1
     78 	"="		color_definition_first
     79 	":"		state_first
     80 	"*&%"		special_character	recolor=-1
     81 .endif
     82 	"\""		string			recolor=-1
     83 .ifdef STRINGS
     84 	"\i"		special_word		mark recolor=-1 buffer
     85 .endif
     86 	"#"		comment			recolor=-1
     87 
     88 
     89 ##############
     90 # Sync Lines #
     91 ##############
     92 
     93 # Following a '-' should be either the number of sync lines or nothing (meaning
     94 # unlimited).  Nothing else other than a comment should appear on the same line.
     95 .ifdef STRINGS
     96 # A sync lines directive should not appear between "[i]strings" and "done".
     97 .else
     98 # If we see a non-digit or a '0', then we have seen the entire sync lines
     99 # directive.  The only thing that may appear on the rest of the line is a
    100 # comment.  Otherwise there may be more digits in the number.
    101 :sync_lines_first Number
    102 	*		comment_or_bad		noeat
    103 	"0"		comment_or_bad
    104 	"1-9"		sync_lines
    105 
    106 # Highlight the remainder of the number.
    107 :sync_lines Number
    108 	*		comment_or_bad		noeat
    109 	"0-9"		sync_lines
    110 .endif
    111 
    112 
    113 ##########################
    114 # Conditional Directives #
    115 ##########################
    116 
    117 # Following a '.' should be a conditional directive.
    118 .ifdef STRINGS
    119 # A conditional directive should not appear between "[i]strings" and "done".
    120 .else
    121 # Start buffering the conditional directive.
    122 :conditional_first Conditional
    123 	*		conditional		noeat buffer
    124 
    125 # Recognize the set of conditional directives.
    126 :conditional Idle
    127 	*		conditional_unknown	noeat strings
    128 	"ifdef"		ifdef_color
    129 	"else"		conditional_color
    130 	"endif"		conditional_color
    131 	"subr"		subr_color
    132 	"end"		conditional_color
    133 	done
    134 	"\c"		conditional
    135 
    136 # We encountered what looks like a conditional directive but is unrecognized as
    137 # such.
    138 :conditional_unknown Idle
    139 .ifdef CHECKING
    140 	*		bad_line		recolormark noeat
    141 .else
    142 	*		comment_or_bad		noeat
    143 .endif
    144 
    145 # We saw a conditional directive that does not take an argument.  Nothing else
    146 # other than a comment should appear on the same line.
    147 :conditional_color Conditional
    148 	*		comment_or_bad		noeat
    149 
    150 # We saw a ".ifdef" which must be followed by a parameter.
    151 :ifdef_color Conditional
    152 	*		need_parameter		noeat
    153 
    154 # We loop over whitespace until we see the first character of the parameter.
    155 :need_parameter Idle
    156 	*		bad			noeat
    157 	" \t"		need_parameter
    158 	"\i"		parameter		recolor=-1
    159 
    160 # Now we highlight the remainder of the parameter.
    161 :parameter Parameter
    162 	*		comment_or_bad		noeat
    163 	"\c"		parameter
    164 
    165 # The following three states are identical to the previous three except the
    166 # color.
    167 :subr_color Conditional
    168 	*		need_subr		noeat
    169 
    170 :need_subr Idle
    171 	*		bad			noeat
    172 	" \t"		need_subr
    173 	"\i"		subr			recolor=-1
    174 
    175 :subr Subr
    176 	*		comment_or_bad		noeat
    177 	"\c"		subr
    178 .endif
    179 
    180 
    181 ####################
    182 # Color Definition #
    183 ####################
    184 
    185 # Following an '=' should be a color definition.
    186 .ifdef STRINGS
    187 # Color definitions should not appear between "[i]strings" and "done".
    188 .else
    189 # A color name must have at least one character.
    190 :color_definition_first Color
    191 	*		color_definition
    192 	" \t#\n"	bad			noeat
    193 
    194 # Highlight any remaining characters until we see whitespace, a comment, or a
    195 # newline.
    196 :color_definition Color
    197 	*		color_definition
    198 	" \t#\n"	colors_ws		noeat
    199 
    200 # The color name may be followed by zero or more standard colors or attributes,
    201 # ending in a comment or newline.
    202 :colors_ws Idle
    203 	*		color_bad		recolor=-1
    204 	" \t"		colors_ws
    205 	"+"		color_ref		recolor=-1
    206 	"#\n"		comment			noeat
    207 
    208 :color_ref ColorRef
    209 	*		colors_ws		noeat
    210 	"\c"		color_ref
    211 
    212 # We have encountered something that is not recognized as a standard color or
    213 # attribute.  Continue to highlight characters as Bad until we see whitespace, a
    214 # comment, or a newline.
    215 :color_bad Bad
    216 	*		color_bad
    217 	" \t#\n"	colors_ws		noeat
    218 .endif
    219 
    220 
    221 #########
    222 # State #
    223 #########
    224 
    225 # Following a ':' should be a state definition.
    226 .ifdef STRINGS
    227 # New states should not appear between "[i]strings" and "done".
    228 .else
    229 # A state name must begin with an alpha character or an underscore.
    230 :state_first State
    231 	*		bad			noeat
    232 	"\i"		state
    233 
    234 # Subsequent characters in a state name must be alpha-numeric or underscores.
    235 :state State
    236 	*		bad			noeat
    237 	"\c"		state
    238 	" \t"		need_state_color	recolor=-1
    239 
    240 # A state must have a color.
    241 :need_state_color Idle
    242 	*		state_color		recolor=-1
    243 	" \t"		need_state_color
    244 	"#\n"		bad			noeat
    245 
    246 # Highlight any remaining characters until we see whitespace, a comment, or a
    247 # newline.
    248 :state_color Color
    249 	*		state_color
    250 	" \t"		context_ws		recolor=-1
    251 	"#\n"		comment_or_bad		noeat
    252 
    253 # Following the state color, there might be one or more contexts.  Loop over
    254 # whitespace until we find something else.
    255 :context_ws Idle
    256 	*		comment_or_bad		noeat
    257 	" \t"		context_ws
    258 	"\i"		context			mark recolor=-1 buffer
    259 
    260 # Here we recognize the possible contexts.
    261 :context Idle
    262 	*		context_unknown		noeat strings
    263 	"comment"	context_color
    264 	"string"	context_color
    265 	done
    266 	"\c"		context
    267 
    268 # We encountered what looks like a context but is unrecognized as such.
    269 :context_unknown Idle
    270 .ifdef CHECKING
    271 	*		context_bad		recolormark noeat
    272 .else
    273 	*		context_ws		noeat
    274 .endif
    275 
    276 # We encountered a valid context.
    277 :context_color Keyword
    278 	*		context_ws		noeat
    279 
    280 # We saw something that is not a valid context name with checking enabled.
    281 # Continue to highlight it as Bad until we see whitespace or a comment.
    282 :context_bad Bad
    283 	*		context_bad
    284 	" \t#\n"	context_ws		noeat
    285 .endif
    286 
    287 
    288 ##############
    289 # Transition #
    290 ##############
    291 
    292 # A state transition starts with a '*', an '&', or a string.
    293 .ifdef STRINGS
    294 # Transitions must start with a string between "[i]strings" and "done".
    295 .else
    296 # We saw either a '*' or an '&'.  Now we need the next state.
    297 :special_character Keyword
    298 	*		need_next_state		noeat
    299 .endif
    300 
    301 # We are in a string.  Continue until we see the close quote or a newline.
    302 # Highlight escaped characters within the string differently.  They start with a
    303 # '\'.
    304 :string String string
    305 	*		string
    306 	"\\"		escape			recolor=-1
    307 	"\""		need_next_state
    308 .ifdef CHECKING
    309 	"\n"		bad
    310 .else
    311 	"\n"		bad			noeat
    312 .endif
    313 
    314 # Highlight an escaped character within a string.
    315 :escape StringEscape string
    316 	*		string
    317 
    318 # Loop over whitespace until we see the first character of the next state.
    319 :need_next_state Idle
    320 	*		bad			noeat
    321 	" \t"		need_next_state
    322 	"\i"		next_state		recolor=-1
    323 
    324 # Now we highlight the remainder of the next state.
    325 :next_state State
    326 	*		bad			noeat
    327 	"\c"		next_state
    328 	" \t"		options_ws
    329 	"#\n"		comment			noeat
    330 
    331 # Following the next state should be zero or more options.  Loop over whitespace
    332 # until we find an option, comment, or newline.
    333 :options_ws Idle
    334 	*		option_bad		recolor=-1
    335 	" \t"		options_ws
    336 	"\i"		option			mark recolor=-1 buffer
    337 	"#\n"		comment			noeat
    338 
    339 # Here we recognize the possible options.  The strings and istrings options
    340 # cannot be used between "[i]strings" and "done".  Since conditional directives
    341 # cannot be used between "[i]strings" and "done" either, the list must be
    342 # duplicated, once without and once with the strings and istrings options.
    343 :option Idle
    344 .ifdef STRINGS
    345 	*		option_unknown		recolormark noeat strings
    346 	"noeat"		option_color
    347 	"recolor"	recolor_color
    348 	"mark"		option_color
    349 	"markend"	option_color
    350 	"recolormark"	option_color
    351 	"buffer"	option_color
    352 	"save_c"	option_color
    353 	"save_s"	option_color
    354 	"hold"		option_color
    355 	"call"		call_color
    356 	"return"	option_color
    357 	"reset"		option_color
    358 	done
    359 .else
    360 	*		option_unknown		recolormark noeat strings
    361 	"noeat"		option_color
    362 	"recolor"	recolor_color
    363 	"mark"		option_color
    364 	"markend"	option_color
    365 	"recolormark"	option_color
    366 	"buffer"	option_color
    367 	"save_c"	option_color
    368 	"save_s"	option_color
    369 	"strings"	strings_color
    370 	"istrings"	strings_color
    371 	"hold"		option_color
    372 	"call"		call_color
    373 	"return"	option_color
    374 	"reset"		option_color
    375 	done
    376 .endif
    377 	"\c"		option
    378 
    379 # We encountered what looks like an option but is unrecognized as such.
    380 :option_unknown Idle
    381 .ifdef CHECKING
    382 	*		option_bad		recolormark noeat
    383 .else
    384 	*		options_ws		noeat
    385 .endif
    386 
    387 # We have encountered an option that does not take an argument.  Highlight it
    388 # and continue to look for more options.
    389 :option_color Keyword
    390 	*		options_ws		noeat
    391 
    392 .ifdef STRINGS
    393 # The strings and istrings options cannot be used between "[i]strings" and
    394 # "done".
    395 .else
    396 # The strings and istrings options are followed by a list of transitions. 
    397 # Rather than duplicate all of the states that highlight transitions, we call
    398 # this entire file as a subroutine and use the STRINGS parameter to disable
    399 # everything else and enable the done keyword.  We return to the comment_or_bad
    400 # state since we will return after seeing the done keyword, and nothing but a
    401 # comment should follow the done keyword.
    402 :strings_color Keyword
    403 	*		comment_or_bad		noeat call=jsf(STRINGS)
    404 .endif
    405 
    406 # Highlight the recolor option.
    407 :recolor_color Keyword
    408 	*		recolor_equal		noeat
    409 
    410 # The recolor option must be followed by an '='.  Loop over whitespace until we
    411 # find one.
    412 :recolor_equal Idle
    413 .ifdef CHECKING
    414 	*		option_bad		recolormark noeat
    415 .else
    416 	*		options_ws		noeat
    417 .endif
    418 	" \t"		recolor_equal
    419 	"="		recolor_minus		mark
    420 
    421 # The recolor option takes an integer argument, and that integer must be
    422 # negative.  Thus the '=' must be followed by a minus sign.  Loop over
    423 # whitespace until we find one.
    424 :recolor_minus Idle
    425 .ifdef CHECKING
    426 	*		option_bad		recolormark noeat
    427 .else
    428 	*		options_ws		noeat
    429 .endif
    430 	" \t"		recolor_minus
    431 	"-"		recolor_amount_first	mark recolor=-1
    432 
    433 # The first digit of the argument to recolor must be non-zero.
    434 :recolor_amount_first Number
    435 .ifdef CHECKING
    436 	*		option_bad		recolormark noeat
    437 .else
    438 	*		options_ws		recolormark noeat
    439 	"0"		option_bad		recolormark noeat
    440 .endif
    441 	"1-9"		recolor_amount
    442 
    443 # Keep highlighting digits until we see something else.
    444 :recolor_amount Number
    445 	*		option_bad		recolormark recolor=-1
    446 	"0-9"		recolor_amount
    447 	" \t#\n"	options_ws		noeat
    448 
    449 # Highlight the call option.
    450 :call_color Keyword
    451 	*		call_equal		noeat
    452 
    453 # The call option must be followed by an '='.  Loop over whitespace until we
    454 # find one.
    455 :call_equal Idle
    456 .ifdef CHECKING
    457 	*		option_bad		recolormark noeat
    458 .else
    459 	*		options_ws		noeat
    460 .endif
    461 	" \t"		call_equal
    462 	"="		call_file_or_dot	mark
    463 
    464 # The first part of the argument to the call option is the name of the file
    465 # containing the subroutine or a '.', implying the current file.  Loop over
    466 # whitespace until we see one of those two things.
    467 :call_file_or_dot Idle
    468 .ifdef CHECKING
    469 	*		option_bad		recolormark noeat
    470 .else
    471 	*		options_ws		noeat
    472 .endif
    473 	" \t"		call_file_or_dot
    474 	"\i"		call_file		mark recolor=-1
    475 	"."		call_dot		mark
    476 
    477 # Highlight the remainder of the file name.  The file name can be followed by a
    478 # '.', which must then be followed by the name of a subroutine, or by a list of
    479 # parameters in parentheses.  The '.', if present, cannot have whitespace on
    480 # either side.
    481 :call_file Subr
    482 .ifdef CHECKING
    483 	*		option_bad		recolormark noeat
    484 .else
    485 	*		options_ws		noeat
    486 .endif
    487 	"\c"		call_file
    488 	"."		call_dot		mark recolor=-1
    489 	" \t("		call_open_paren		noeat
    490 
    491 # We saw a '.'.  The next character must start the name of a subroutine.
    492 :call_dot Idle
    493 .ifdef CHECKING
    494 	*		option_bad		recolormark noeat
    495 .else
    496 	*		options_ws		noeat
    497 .endif
    498 	"("		call_dot_bad		recolormark noeat
    499 	"\i"		call_subr		mark recolor=-1
    500 
    501 # We have seen a dot followed by an open parenthesis.  A dot must be followed by
    502 # a subroutine name.  Highlight the dot as Bad.
    503 :call_dot_bad Bad
    504 	*		call_open_paren		noeat
    505 
    506 # Highlight the remainder of the subroutine name.  Following the subroutine name
    507 # must be a list of parameters in parentheses, possibly preceded by whitespace.
    508 :call_subr Subr
    509 .ifdef CHECKING
    510 	*		option_bad		recolormark noeat
    511 .else
    512 	*		options_ws		noeat
    513 .endif
    514 	"\c"		call_subr
    515 	" \t("		call_open_paren		noeat
    516 
    517 # Loop over whitespace until we find the open parenthesis.
    518 :call_open_paren Idle
    519 .ifdef CHECKING
    520 	*		option_bad		recolormark noeat
    521 .else
    522 	*		options_ws		noeat
    523 .endif
    524 	" \t"		call_open_paren
    525 	"("		call_parameters_ws
    526 
    527 # The list of parameters is delimited by whitespace.  Loop over whitespace until
    528 # we find either the beginning of a parameter or a close parenthesis.  We should
    529 # not see a comment or newline since the list should be terminated by a close
    530 # parenthesis.
    531 :call_parameters_ws Idle
    532 	*		call_parameter_bad	recolor=-1
    533 	" \t"		call_parameters_ws
    534 	"-"		call_parameter_undef
    535 	"\i"		call_parameter		recolor=-1
    536 	")"		options_ws
    537 	"#\n"		bad			noeat
    538 
    539 # We saw a "-".  The next character should start the parameter being undefined.
    540 :call_parameter_undef Parameter
    541 	*		call_parameters_ws	noeat
    542 	"\i"		call_parameter		recolor=-2
    543 
    544 # Highlight the remainder of the parameter.
    545 :call_parameter Parameter
    546 	*		call_parameters_ws	noeat
    547 	"\c"		call_parameter
    548 
    549 # We saw something that is not a valid parameter name.  Continue to highlight it
    550 # as Bad until we see whitespace.
    551 :call_parameter_bad Bad
    552 	*		call_parameter_bad
    553 	") \t#\n"	call_parameters_ws	noeat
    554 
    555 # We saw something that is not a valid option name.  Continue to highlight it as
    556 # Bad until we see whitespace or a comment.
    557 :option_bad Bad
    558 	*		option_bad
    559 	" \t#\n"	options_ws		noeat
    560 
    561 
    562 ########
    563 # Done #
    564 ########
    565 
    566 .ifdef STRINGS
    567 # The special word, "done", can only be used after a strings or istrings option.
    568 # Recognize the done keyword.
    569 :special_word Idle
    570 	*		bad_line		recolormark noeat strings
    571 	"done"		done_color
    572 	done
    573 	"\c"		special_word
    574 
    575 # Highlight the done keyword and return to highlighting things normally, since
    576 # the list of strings has been terminated.
    577 :done_color Keyword
    578 	*		comment_or_bad		return noeat
    579 .endif
    580 
    581 
    582 ##################
    583 # Comment or Bad #
    584 ##################
    585 
    586 # We have seen everything that should appear on the current line except an
    587 # optional comment.  Loop over whitespace until we find a comment or newline.
    588 :comment_or_bad Idle
    589 	*		bad			noeat
    590 	" \t"		comment_or_bad
    591 	"#\n"		comment			noeat
    592 
    593 
    594 ###########
    595 # Comment #
    596 ###########
    597 
    598 # Continue to highlight the comment until the end of the line.
    599 :comment Comment comment
    600 	*		comment
    601 	"BFHNTX"	comment			noeat call=comment_todo.comment_todo()
    602 	"\n"		idle
    603 
    604 
    605 #######
    606 # Bad #
    607 #######
    608 
    609 .ifdef CHECKING
    610 # We have encountered incorrect syntax.  Loop over whitespace until we see the
    611 # first visible character.  Highlight that character and the rest of the line as
    612 # Bad.
    613 :bad Bad
    614 	*		bad_line
    615 	" \t\n"		bad
    616 .else
    617 # When not performing strict checking, don't go searching for the next visible
    618 # character to highlight as Bad.  Simply highlight the rest of the line as Bad,
    619 # even if it is invisible.
    620 :bad Bad
    621 	*		bad_line		noeat
    622 .endif
    623 
    624 # Continue to highlight everything as Bad until the end of the line.
    625 :bad_line Bad
    626 	*		bad_line
    627 	"\n"		idle