init
This commit is contained in:
		
							
								
								
									
										627
									
								
								syntax/jsf.jsf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										627
									
								
								syntax/jsf.jsf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,627 @@
 | 
			
		||||
# JOE Syntax-Highlighting Description
 | 
			
		||||
#                 for
 | 
			
		||||
# JOE Syntax-Highlighting Descriptions
 | 
			
		||||
#
 | 
			
		||||
# Author: Charles J. Tabony
 | 
			
		||||
# Date:   2007-2-13
 | 
			
		||||
#
 | 
			
		||||
# This is a highlighting description for files like this one.
 | 
			
		||||
#
 | 
			
		||||
# When CHECKING is defined, it is very aggressive about error checking.  The
 | 
			
		||||
# idea is that anywhere the highlighted file contains a syntax error, at least
 | 
			
		||||
# one visible character should be highlighted as Bad.  While that feature is
 | 
			
		||||
# useful for finding syntax errors, it is annoying when editing a file, since
 | 
			
		||||
# nearly everything is an error until you finish typing it.
 | 
			
		||||
#
 | 
			
		||||
# In order to not annoy people by default, but keep the option of strictly
 | 
			
		||||
# checking syntax, I predicated the stricter checking on the CHECKING parameter. 
 | 
			
		||||
# By default, things that are incomplete are generally not marked as errors. 
 | 
			
		||||
# Only things that appear to be actual mistakes are highlighted as Bad.  To
 | 
			
		||||
# enable the stricter checking, one can highlight the file with the jsf_check
 | 
			
		||||
# syntax.  jsf_check.jsf simply calls the entire jsf.jsf file with CHECKING
 | 
			
		||||
# defined.
 | 
			
		||||
#
 | 
			
		||||
# The idea is for authors of a jsf file to edit their file, highlight it with
 | 
			
		||||
# jsf_check, and then look for any red characters.  That way they can check for
 | 
			
		||||
# syntax errors before testing the changes.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#####################
 | 
			
		||||
# Color Definitions #
 | 
			
		||||
#####################
 | 
			
		||||
 | 
			
		||||
=Idle
 | 
			
		||||
=Comment
 | 
			
		||||
=Conditional	+Precond +Preproc
 | 
			
		||||
=Parameter	+Ident
 | 
			
		||||
=Keyword
 | 
			
		||||
=Color		+Type
 | 
			
		||||
=ColorRef
 | 
			
		||||
=State		+Ident
 | 
			
		||||
=Subr		+Ident
 | 
			
		||||
=Constant
 | 
			
		||||
=Number		+Constant
 | 
			
		||||
=String		+Constant
 | 
			
		||||
=StringEscape	+Escape +String
 | 
			
		||||
=Bad
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##################
 | 
			
		||||
# Initial States #
 | 
			
		||||
##################
 | 
			
		||||
 | 
			
		||||
# This is a dummy state that simply jumps to comment_or_bad.  It is here so that
 | 
			
		||||
# when this file calls itself with the STRINGS parameter defined, comment_or_bad
 | 
			
		||||
# will effectively be the initial state.  comment_or_bad should be the initial
 | 
			
		||||
# state because strings and istrings options can only be used as the last option
 | 
			
		||||
# of a transition.
 | 
			
		||||
.ifdef STRINGS
 | 
			
		||||
:strings_initial Idle
 | 
			
		||||
	*		comment_or_bad		noeat
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
# Each new line (that is not considered bad from the beginning) begins in the
 | 
			
		||||
# idle state.  The first non-whitespace character determines what the rest of
 | 
			
		||||
# the line should contain.  Following a strings or istrings option, only strings
 | 
			
		||||
# and comments are allowed until the word "done" denotes the end of the list.
 | 
			
		||||
:idle Idle
 | 
			
		||||
	*		bad			noeat
 | 
			
		||||
	" \t\n"		idle
 | 
			
		||||
.ifdef STRINGS
 | 
			
		||||
.else
 | 
			
		||||
	"-"		sync_lines_first
 | 
			
		||||
	"."		conditional_first	mark recolor=-1
 | 
			
		||||
	"="		color_definition_first
 | 
			
		||||
	":"		state_first
 | 
			
		||||
	"*&%"		special_character	recolor=-1
 | 
			
		||||
.endif
 | 
			
		||||
	"\""		string			recolor=-1
 | 
			
		||||
.ifdef STRINGS
 | 
			
		||||
	"\i"		special_word		mark recolor=-1 buffer
 | 
			
		||||
.endif
 | 
			
		||||
	"#"		comment			recolor=-1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############
 | 
			
		||||
# Sync Lines #
 | 
			
		||||
##############
 | 
			
		||||
 | 
			
		||||
# Following a '-' should be either the number of sync lines or nothing (meaning
 | 
			
		||||
# unlimited).  Nothing else other than a comment should appear on the same line.
 | 
			
		||||
.ifdef STRINGS
 | 
			
		||||
# A sync lines directive should not appear between "[i]strings" and "done".
 | 
			
		||||
.else
 | 
			
		||||
# If we see a non-digit or a '0', then we have seen the entire sync lines
 | 
			
		||||
# directive.  The only thing that may appear on the rest of the line is a
 | 
			
		||||
# comment.  Otherwise there may be more digits in the number.
 | 
			
		||||
:sync_lines_first Number
 | 
			
		||||
	*		comment_or_bad		noeat
 | 
			
		||||
	"0"		comment_or_bad
 | 
			
		||||
	"1-9"		sync_lines
 | 
			
		||||
 | 
			
		||||
# Highlight the remainder of the number.
 | 
			
		||||
:sync_lines Number
 | 
			
		||||
	*		comment_or_bad		noeat
 | 
			
		||||
	"0-9"		sync_lines
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##########################
 | 
			
		||||
# Conditional Directives #
 | 
			
		||||
##########################
 | 
			
		||||
 | 
			
		||||
# Following a '.' should be a conditional directive.
 | 
			
		||||
.ifdef STRINGS
 | 
			
		||||
# A conditional directive should not appear between "[i]strings" and "done".
 | 
			
		||||
.else
 | 
			
		||||
# Start buffering the conditional directive.
 | 
			
		||||
:conditional_first Conditional
 | 
			
		||||
	*		conditional		noeat buffer
 | 
			
		||||
 | 
			
		||||
# Recognize the set of conditional directives.
 | 
			
		||||
:conditional Idle
 | 
			
		||||
	*		conditional_unknown	noeat strings
 | 
			
		||||
	"ifdef"		ifdef_color
 | 
			
		||||
	"else"		conditional_color
 | 
			
		||||
	"endif"		conditional_color
 | 
			
		||||
	"subr"		subr_color
 | 
			
		||||
	"end"		conditional_color
 | 
			
		||||
	done
 | 
			
		||||
	"\c"		conditional
 | 
			
		||||
 | 
			
		||||
# We encountered what looks like a conditional directive but is unrecognized as
 | 
			
		||||
# such.
 | 
			
		||||
:conditional_unknown Idle
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	*		bad_line		recolormark noeat
 | 
			
		||||
.else
 | 
			
		||||
	*		comment_or_bad		noeat
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
# We saw a conditional directive that does not take an argument.  Nothing else
 | 
			
		||||
# other than a comment should appear on the same line.
 | 
			
		||||
:conditional_color Conditional
 | 
			
		||||
	*		comment_or_bad		noeat
 | 
			
		||||
 | 
			
		||||
# We saw a ".ifdef" which must be followed by a parameter.
 | 
			
		||||
:ifdef_color Conditional
 | 
			
		||||
	*		need_parameter		noeat
 | 
			
		||||
 | 
			
		||||
# We loop over whitespace until we see the first character of the parameter.
 | 
			
		||||
:need_parameter Idle
 | 
			
		||||
	*		bad			noeat
 | 
			
		||||
	" \t"		need_parameter
 | 
			
		||||
	"\i"		parameter		recolor=-1
 | 
			
		||||
 | 
			
		||||
# Now we highlight the remainder of the parameter.
 | 
			
		||||
:parameter Parameter
 | 
			
		||||
	*		comment_or_bad		noeat
 | 
			
		||||
	"\c"		parameter
 | 
			
		||||
 | 
			
		||||
# The following three states are identical to the previous three except the
 | 
			
		||||
# color.
 | 
			
		||||
:subr_color Conditional
 | 
			
		||||
	*		need_subr		noeat
 | 
			
		||||
 | 
			
		||||
:need_subr Idle
 | 
			
		||||
	*		bad			noeat
 | 
			
		||||
	" \t"		need_subr
 | 
			
		||||
	"\i"		subr			recolor=-1
 | 
			
		||||
 | 
			
		||||
:subr Subr
 | 
			
		||||
	*		comment_or_bad		noeat
 | 
			
		||||
	"\c"		subr
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
####################
 | 
			
		||||
# Color Definition #
 | 
			
		||||
####################
 | 
			
		||||
 | 
			
		||||
# Following an '=' should be a color definition.
 | 
			
		||||
.ifdef STRINGS
 | 
			
		||||
# Color definitions should not appear between "[i]strings" and "done".
 | 
			
		||||
.else
 | 
			
		||||
# A color name must have at least one character.
 | 
			
		||||
:color_definition_first Color
 | 
			
		||||
	*		color_definition
 | 
			
		||||
	" \t#\n"	bad			noeat
 | 
			
		||||
 | 
			
		||||
# Highlight any remaining characters until we see whitespace, a comment, or a
 | 
			
		||||
# newline.
 | 
			
		||||
:color_definition Color
 | 
			
		||||
	*		color_definition
 | 
			
		||||
	" \t#\n"	colors_ws		noeat
 | 
			
		||||
 | 
			
		||||
# The color name may be followed by zero or more standard colors or attributes,
 | 
			
		||||
# ending in a comment or newline.
 | 
			
		||||
:colors_ws Idle
 | 
			
		||||
	*		color_bad		recolor=-1
 | 
			
		||||
	" \t"		colors_ws
 | 
			
		||||
	"+"		color_ref		recolor=-1
 | 
			
		||||
	"#\n"		comment			noeat
 | 
			
		||||
 | 
			
		||||
:color_ref ColorRef
 | 
			
		||||
	*		colors_ws		noeat
 | 
			
		||||
	"\c"		color_ref
 | 
			
		||||
 | 
			
		||||
# We have encountered something that is not recognized as a standard color or
 | 
			
		||||
# attribute.  Continue to highlight characters as Bad until we see whitespace, a
 | 
			
		||||
# comment, or a newline.
 | 
			
		||||
:color_bad Bad
 | 
			
		||||
	*		color_bad
 | 
			
		||||
	" \t#\n"	colors_ws		noeat
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#########
 | 
			
		||||
# State #
 | 
			
		||||
#########
 | 
			
		||||
 | 
			
		||||
# Following a ':' should be a state definition.
 | 
			
		||||
.ifdef STRINGS
 | 
			
		||||
# New states should not appear between "[i]strings" and "done".
 | 
			
		||||
.else
 | 
			
		||||
# A state name must begin with an alpha character or an underscore.
 | 
			
		||||
:state_first State
 | 
			
		||||
	*		bad			noeat
 | 
			
		||||
	"\i"		state
 | 
			
		||||
 | 
			
		||||
# Subsequent characters in a state name must be alpha-numeric or underscores.
 | 
			
		||||
:state State
 | 
			
		||||
	*		bad			noeat
 | 
			
		||||
	"\c"		state
 | 
			
		||||
	" \t"		need_state_color	recolor=-1
 | 
			
		||||
 | 
			
		||||
# A state must have a color.
 | 
			
		||||
:need_state_color Idle
 | 
			
		||||
	*		state_color		recolor=-1
 | 
			
		||||
	" \t"		need_state_color
 | 
			
		||||
	"#\n"		bad			noeat
 | 
			
		||||
 | 
			
		||||
# Highlight any remaining characters until we see whitespace, a comment, or a
 | 
			
		||||
# newline.
 | 
			
		||||
:state_color Color
 | 
			
		||||
	*		state_color
 | 
			
		||||
	" \t"		context_ws		recolor=-1
 | 
			
		||||
	"#\n"		comment_or_bad		noeat
 | 
			
		||||
 | 
			
		||||
# Following the state color, there might be one or more contexts.  Loop over
 | 
			
		||||
# whitespace until we find something else.
 | 
			
		||||
:context_ws Idle
 | 
			
		||||
	*		comment_or_bad		noeat
 | 
			
		||||
	" \t"		context_ws
 | 
			
		||||
	"\i"		context			mark recolor=-1 buffer
 | 
			
		||||
 | 
			
		||||
# Here we recognize the possible contexts.
 | 
			
		||||
:context Idle
 | 
			
		||||
	*		context_unknown		noeat strings
 | 
			
		||||
	"comment"	context_color
 | 
			
		||||
	"string"	context_color
 | 
			
		||||
	done
 | 
			
		||||
	"\c"		context
 | 
			
		||||
 | 
			
		||||
# We encountered what looks like a context but is unrecognized as such.
 | 
			
		||||
:context_unknown Idle
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	*		context_bad		recolormark noeat
 | 
			
		||||
.else
 | 
			
		||||
	*		context_ws		noeat
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
# We encountered a valid context.
 | 
			
		||||
:context_color Keyword
 | 
			
		||||
	*		context_ws		noeat
 | 
			
		||||
 | 
			
		||||
# We saw something that is not a valid context name with checking enabled.
 | 
			
		||||
# Continue to highlight it as Bad until we see whitespace or a comment.
 | 
			
		||||
:context_bad Bad
 | 
			
		||||
	*		context_bad
 | 
			
		||||
	" \t#\n"	context_ws		noeat
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############
 | 
			
		||||
# Transition #
 | 
			
		||||
##############
 | 
			
		||||
 | 
			
		||||
# A state transition starts with a '*', an '&', or a string.
 | 
			
		||||
.ifdef STRINGS
 | 
			
		||||
# Transitions must start with a string between "[i]strings" and "done".
 | 
			
		||||
.else
 | 
			
		||||
# We saw either a '*' or an '&'.  Now we need the next state.
 | 
			
		||||
:special_character Keyword
 | 
			
		||||
	*		need_next_state		noeat
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
# We are in a string.  Continue until we see the close quote or a newline.
 | 
			
		||||
# Highlight escaped characters within the string differently.  They start with a
 | 
			
		||||
# '\'.
 | 
			
		||||
:string String string
 | 
			
		||||
	*		string
 | 
			
		||||
	"\\"		escape			recolor=-1
 | 
			
		||||
	"\""		need_next_state
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	"\n"		bad
 | 
			
		||||
.else
 | 
			
		||||
	"\n"		bad			noeat
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
# Highlight an escaped character within a string.
 | 
			
		||||
:escape StringEscape string
 | 
			
		||||
	*		string
 | 
			
		||||
 | 
			
		||||
# Loop over whitespace until we see the first character of the next state.
 | 
			
		||||
:need_next_state Idle
 | 
			
		||||
	*		bad			noeat
 | 
			
		||||
	" \t"		need_next_state
 | 
			
		||||
	"\i"		next_state		recolor=-1
 | 
			
		||||
 | 
			
		||||
# Now we highlight the remainder of the next state.
 | 
			
		||||
:next_state State
 | 
			
		||||
	*		bad			noeat
 | 
			
		||||
	"\c"		next_state
 | 
			
		||||
	" \t"		options_ws
 | 
			
		||||
	"#\n"		comment			noeat
 | 
			
		||||
 | 
			
		||||
# Following the next state should be zero or more options.  Loop over whitespace
 | 
			
		||||
# until we find an option, comment, or newline.
 | 
			
		||||
:options_ws Idle
 | 
			
		||||
	*		option_bad		recolor=-1
 | 
			
		||||
	" \t"		options_ws
 | 
			
		||||
	"\i"		option			mark recolor=-1 buffer
 | 
			
		||||
	"#\n"		comment			noeat
 | 
			
		||||
 | 
			
		||||
# Here we recognize the possible options.  The strings and istrings options
 | 
			
		||||
# cannot be used between "[i]strings" and "done".  Since conditional directives
 | 
			
		||||
# cannot be used between "[i]strings" and "done" either, the list must be
 | 
			
		||||
# duplicated, once without and once with the strings and istrings options.
 | 
			
		||||
:option Idle
 | 
			
		||||
.ifdef STRINGS
 | 
			
		||||
	*		option_unknown		recolormark noeat strings
 | 
			
		||||
	"noeat"		option_color
 | 
			
		||||
	"recolor"	recolor_color
 | 
			
		||||
	"mark"		option_color
 | 
			
		||||
	"markend"	option_color
 | 
			
		||||
	"recolormark"	option_color
 | 
			
		||||
	"buffer"	option_color
 | 
			
		||||
	"save_c"	option_color
 | 
			
		||||
	"save_s"	option_color
 | 
			
		||||
	"hold"		option_color
 | 
			
		||||
	"call"		call_color
 | 
			
		||||
	"return"	option_color
 | 
			
		||||
	"reset"		option_color
 | 
			
		||||
	done
 | 
			
		||||
.else
 | 
			
		||||
	*		option_unknown		recolormark noeat strings
 | 
			
		||||
	"noeat"		option_color
 | 
			
		||||
	"recolor"	recolor_color
 | 
			
		||||
	"mark"		option_color
 | 
			
		||||
	"markend"	option_color
 | 
			
		||||
	"recolormark"	option_color
 | 
			
		||||
	"buffer"	option_color
 | 
			
		||||
	"save_c"	option_color
 | 
			
		||||
	"save_s"	option_color
 | 
			
		||||
	"strings"	strings_color
 | 
			
		||||
	"istrings"	strings_color
 | 
			
		||||
	"hold"		option_color
 | 
			
		||||
	"call"		call_color
 | 
			
		||||
	"return"	option_color
 | 
			
		||||
	"reset"		option_color
 | 
			
		||||
	done
 | 
			
		||||
.endif
 | 
			
		||||
	"\c"		option
 | 
			
		||||
 | 
			
		||||
# We encountered what looks like an option but is unrecognized as such.
 | 
			
		||||
:option_unknown Idle
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	*		option_bad		recolormark noeat
 | 
			
		||||
.else
 | 
			
		||||
	*		options_ws		noeat
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
# We have encountered an option that does not take an argument.  Highlight it
 | 
			
		||||
# and continue to look for more options.
 | 
			
		||||
:option_color Keyword
 | 
			
		||||
	*		options_ws		noeat
 | 
			
		||||
 | 
			
		||||
.ifdef STRINGS
 | 
			
		||||
# The strings and istrings options cannot be used between "[i]strings" and
 | 
			
		||||
# "done".
 | 
			
		||||
.else
 | 
			
		||||
# The strings and istrings options are followed by a list of transitions. 
 | 
			
		||||
# Rather than duplicate all of the states that highlight transitions, we call
 | 
			
		||||
# this entire file as a subroutine and use the STRINGS parameter to disable
 | 
			
		||||
# everything else and enable the done keyword.  We return to the comment_or_bad
 | 
			
		||||
# state since we will return after seeing the done keyword, and nothing but a
 | 
			
		||||
# comment should follow the done keyword.
 | 
			
		||||
:strings_color Keyword
 | 
			
		||||
	*		comment_or_bad		noeat call=jsf(STRINGS)
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
# Highlight the recolor option.
 | 
			
		||||
:recolor_color Keyword
 | 
			
		||||
	*		recolor_equal		noeat
 | 
			
		||||
 | 
			
		||||
# The recolor option must be followed by an '='.  Loop over whitespace until we
 | 
			
		||||
# find one.
 | 
			
		||||
:recolor_equal Idle
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	*		option_bad		recolormark noeat
 | 
			
		||||
.else
 | 
			
		||||
	*		options_ws		noeat
 | 
			
		||||
.endif
 | 
			
		||||
	" \t"		recolor_equal
 | 
			
		||||
	"="		recolor_minus		mark
 | 
			
		||||
 | 
			
		||||
# The recolor option takes an integer argument, and that integer must be
 | 
			
		||||
# negative.  Thus the '=' must be followed by a minus sign.  Loop over
 | 
			
		||||
# whitespace until we find one.
 | 
			
		||||
:recolor_minus Idle
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	*		option_bad		recolormark noeat
 | 
			
		||||
.else
 | 
			
		||||
	*		options_ws		noeat
 | 
			
		||||
.endif
 | 
			
		||||
	" \t"		recolor_minus
 | 
			
		||||
	"-"		recolor_amount_first	mark recolor=-1
 | 
			
		||||
 | 
			
		||||
# The first digit of the argument to recolor must be non-zero.
 | 
			
		||||
:recolor_amount_first Number
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	*		option_bad		recolormark noeat
 | 
			
		||||
.else
 | 
			
		||||
	*		options_ws		recolormark noeat
 | 
			
		||||
	"0"		option_bad		recolormark noeat
 | 
			
		||||
.endif
 | 
			
		||||
	"1-9"		recolor_amount
 | 
			
		||||
 | 
			
		||||
# Keep highlighting digits until we see something else.
 | 
			
		||||
:recolor_amount Number
 | 
			
		||||
	*		option_bad		recolormark recolor=-1
 | 
			
		||||
	"0-9"		recolor_amount
 | 
			
		||||
	" \t#\n"	options_ws		noeat
 | 
			
		||||
 | 
			
		||||
# Highlight the call option.
 | 
			
		||||
:call_color Keyword
 | 
			
		||||
	*		call_equal		noeat
 | 
			
		||||
 | 
			
		||||
# The call option must be followed by an '='.  Loop over whitespace until we
 | 
			
		||||
# find one.
 | 
			
		||||
:call_equal Idle
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	*		option_bad		recolormark noeat
 | 
			
		||||
.else
 | 
			
		||||
	*		options_ws		noeat
 | 
			
		||||
.endif
 | 
			
		||||
	" \t"		call_equal
 | 
			
		||||
	"="		call_file_or_dot	mark
 | 
			
		||||
 | 
			
		||||
# The first part of the argument to the call option is the name of the file
 | 
			
		||||
# containing the subroutine or a '.', implying the current file.  Loop over
 | 
			
		||||
# whitespace until we see one of those two things.
 | 
			
		||||
:call_file_or_dot Idle
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	*		option_bad		recolormark noeat
 | 
			
		||||
.else
 | 
			
		||||
	*		options_ws		noeat
 | 
			
		||||
.endif
 | 
			
		||||
	" \t"		call_file_or_dot
 | 
			
		||||
	"\i"		call_file		mark recolor=-1
 | 
			
		||||
	"."		call_dot		mark
 | 
			
		||||
 | 
			
		||||
# Highlight the remainder of the file name.  The file name can be followed by a
 | 
			
		||||
# '.', which must then be followed by the name of a subroutine, or by a list of
 | 
			
		||||
# parameters in parentheses.  The '.', if present, cannot have whitespace on
 | 
			
		||||
# either side.
 | 
			
		||||
:call_file Subr
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	*		option_bad		recolormark noeat
 | 
			
		||||
.else
 | 
			
		||||
	*		options_ws		noeat
 | 
			
		||||
.endif
 | 
			
		||||
	"\c"		call_file
 | 
			
		||||
	"."		call_dot		mark recolor=-1
 | 
			
		||||
	" \t("		call_open_paren		noeat
 | 
			
		||||
 | 
			
		||||
# We saw a '.'.  The next character must start the name of a subroutine.
 | 
			
		||||
:call_dot Idle
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	*		option_bad		recolormark noeat
 | 
			
		||||
.else
 | 
			
		||||
	*		options_ws		noeat
 | 
			
		||||
.endif
 | 
			
		||||
	"("		call_dot_bad		recolormark noeat
 | 
			
		||||
	"\i"		call_subr		mark recolor=-1
 | 
			
		||||
 | 
			
		||||
# We have seen a dot followed by an open parenthesis.  A dot must be followed by
 | 
			
		||||
# a subroutine name.  Highlight the dot as Bad.
 | 
			
		||||
:call_dot_bad Bad
 | 
			
		||||
	*		call_open_paren		noeat
 | 
			
		||||
 | 
			
		||||
# Highlight the remainder of the subroutine name.  Following the subroutine name
 | 
			
		||||
# must be a list of parameters in parentheses, possibly preceded by whitespace.
 | 
			
		||||
:call_subr Subr
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	*		option_bad		recolormark noeat
 | 
			
		||||
.else
 | 
			
		||||
	*		options_ws		noeat
 | 
			
		||||
.endif
 | 
			
		||||
	"\c"		call_subr
 | 
			
		||||
	" \t("		call_open_paren		noeat
 | 
			
		||||
 | 
			
		||||
# Loop over whitespace until we find the open parenthesis.
 | 
			
		||||
:call_open_paren Idle
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
	*		option_bad		recolormark noeat
 | 
			
		||||
.else
 | 
			
		||||
	*		options_ws		noeat
 | 
			
		||||
.endif
 | 
			
		||||
	" \t"		call_open_paren
 | 
			
		||||
	"("		call_parameters_ws
 | 
			
		||||
 | 
			
		||||
# The list of parameters is delimited by whitespace.  Loop over whitespace until
 | 
			
		||||
# we find either the beginning of a parameter or a close parenthesis.  We should
 | 
			
		||||
# not see a comment or newline since the list should be terminated by a close
 | 
			
		||||
# parenthesis.
 | 
			
		||||
:call_parameters_ws Idle
 | 
			
		||||
	*		call_parameter_bad	recolor=-1
 | 
			
		||||
	" \t"		call_parameters_ws
 | 
			
		||||
	"-"		call_parameter_undef
 | 
			
		||||
	"\i"		call_parameter		recolor=-1
 | 
			
		||||
	")"		options_ws
 | 
			
		||||
	"#\n"		bad			noeat
 | 
			
		||||
 | 
			
		||||
# We saw a "-".  The next character should start the parameter being undefined.
 | 
			
		||||
:call_parameter_undef Parameter
 | 
			
		||||
	*		call_parameters_ws	noeat
 | 
			
		||||
	"\i"		call_parameter		recolor=-2
 | 
			
		||||
 | 
			
		||||
# Highlight the remainder of the parameter.
 | 
			
		||||
:call_parameter Parameter
 | 
			
		||||
	*		call_parameters_ws	noeat
 | 
			
		||||
	"\c"		call_parameter
 | 
			
		||||
 | 
			
		||||
# We saw something that is not a valid parameter name.  Continue to highlight it
 | 
			
		||||
# as Bad until we see whitespace.
 | 
			
		||||
:call_parameter_bad Bad
 | 
			
		||||
	*		call_parameter_bad
 | 
			
		||||
	") \t#\n"	call_parameters_ws	noeat
 | 
			
		||||
 | 
			
		||||
# We saw something that is not a valid option name.  Continue to highlight it as
 | 
			
		||||
# Bad until we see whitespace or a comment.
 | 
			
		||||
:option_bad Bad
 | 
			
		||||
	*		option_bad
 | 
			
		||||
	" \t#\n"	options_ws		noeat
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
########
 | 
			
		||||
# Done #
 | 
			
		||||
########
 | 
			
		||||
 | 
			
		||||
.ifdef STRINGS
 | 
			
		||||
# The special word, "done", can only be used after a strings or istrings option.
 | 
			
		||||
# Recognize the done keyword.
 | 
			
		||||
:special_word Idle
 | 
			
		||||
	*		bad_line		recolormark noeat strings
 | 
			
		||||
	"done"		done_color
 | 
			
		||||
	done
 | 
			
		||||
	"\c"		special_word
 | 
			
		||||
 | 
			
		||||
# Highlight the done keyword and return to highlighting things normally, since
 | 
			
		||||
# the list of strings has been terminated.
 | 
			
		||||
:done_color Keyword
 | 
			
		||||
	*		comment_or_bad		return noeat
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##################
 | 
			
		||||
# Comment or Bad #
 | 
			
		||||
##################
 | 
			
		||||
 | 
			
		||||
# We have seen everything that should appear on the current line except an
 | 
			
		||||
# optional comment.  Loop over whitespace until we find a comment or newline.
 | 
			
		||||
:comment_or_bad Idle
 | 
			
		||||
	*		bad			noeat
 | 
			
		||||
	" \t"		comment_or_bad
 | 
			
		||||
	"#\n"		comment			noeat
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
###########
 | 
			
		||||
# Comment #
 | 
			
		||||
###########
 | 
			
		||||
 | 
			
		||||
# Continue to highlight the comment until the end of the line.
 | 
			
		||||
:comment Comment comment
 | 
			
		||||
	*		comment
 | 
			
		||||
	"BFHNTX"	comment			noeat call=comment_todo.comment_todo()
 | 
			
		||||
	"\n"		idle
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#######
 | 
			
		||||
# Bad #
 | 
			
		||||
#######
 | 
			
		||||
 | 
			
		||||
.ifdef CHECKING
 | 
			
		||||
# We have encountered incorrect syntax.  Loop over whitespace until we see the
 | 
			
		||||
# first visible character.  Highlight that character and the rest of the line as
 | 
			
		||||
# Bad.
 | 
			
		||||
:bad Bad
 | 
			
		||||
	*		bad_line
 | 
			
		||||
	" \t\n"		bad
 | 
			
		||||
.else
 | 
			
		||||
# When not performing strict checking, don't go searching for the next visible
 | 
			
		||||
# character to highlight as Bad.  Simply highlight the rest of the line as Bad,
 | 
			
		||||
# even if it is invisible.
 | 
			
		||||
:bad Bad
 | 
			
		||||
	*		bad_line		noeat
 | 
			
		||||
.endif
 | 
			
		||||
 | 
			
		||||
# Continue to highlight everything as Bad until the end of the line.
 | 
			
		||||
:bad_line Bad
 | 
			
		||||
	*		bad_line
 | 
			
		||||
	"\n"		idle
 | 
			
		||||
		Reference in New Issue
	
	Block a user