129 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			129 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								README for testing lexers with lexilla/test.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The TestLexers application is run to test the lexing and folding of a set of example
							 | 
						||
| 
								 | 
							
								files and thus ensure that the lexers are working correctly.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Lexers are accessed through the Lexilla shared library which must be built first
							 | 
						||
| 
								 | 
							
								in the lexilla/src directory.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TestLexers works on Windows, Linux, or macOS and requires a C++20 compiler.
							 | 
						||
| 
								 | 
							
								MSVC 2019.4, GCC 9.0, Clang 9.0, and Apple Clang 11.0 are known to work.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								MSVC is only available on Windows.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								GCC and Clang work on Windows and Linux.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								On macOS, only Apple Clang is available.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Lexilla requires some headers from Scintilla to build and expects a directory named
							 | 
						||
| 
								 | 
							
								"scintilla" containing a copy of Scintilla 5+ to be a peer of the Lexilla top level
							 | 
						||
| 
								 | 
							
								directory conventionally called "lexilla".
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								To use GCC run lexilla/test/makefile:
							 | 
						||
| 
								 | 
							
									make test
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								To use Clang run lexilla/test/makefile:
							 | 
						||
| 
								 | 
							
									make CLANG=1 test
							 | 
						||
| 
								 | 
							
								On macOS, CLANG is set automatically so this can just be
							 | 
						||
| 
								 | 
							
									make test
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								To use MSVC:
							 | 
						||
| 
								 | 
							
									nmake -f testlexers.mak test
							 | 
						||
| 
								 | 
							
								There is also a project file TestLexers.vcxproj that can be loaded into the Visual
							 | 
						||
| 
								 | 
							
								C++ IDE.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Adding or Changing Tests
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The lexilla/test/examples directory contains a set of tests located in a tree of
							 | 
						||
| 
								 | 
							
								subdirectories.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Each directory contains example files along with control files called
							 | 
						||
| 
								 | 
							
								SciTE.properties and expected result files with .styled and .folded suffixes.
							 | 
						||
| 
								 | 
							
								If an unexpected result occurs then files with the additional suffix .new 
							 | 
						||
| 
								 | 
							
								(that is .styled.new or .folded.new) may be created.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Each file in the examples tree that does not have an extension of .properties, .styled,
							 | 
						||
| 
								 | 
							
								.folded or .new is an example file that will be lexed and folded according to settings
							 | 
						||
| 
								 | 
							
								found in SciTE.properties.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The results of the lex will be compared to the corresponding .styled file and if different
							 | 
						||
| 
								 | 
							
								the result will be saved to a .styled.new file for checking.
							 | 
						||
| 
								 | 
							
								So, if x.cxx is the example, its lexed form will be checked against x.cxx.styled and a
							 | 
						||
| 
								 | 
							
								x.cxx.styled.new file may be created. The .styled.new and .styled files contain the text
							 | 
						||
| 
								 | 
							
								of the original file along with style number changes in {} like:
							 | 
						||
| 
								 | 
							
									{5}function{0} {11}first{10}(){0}
							 | 
						||
| 
								 | 
							
								After checking that the .styled.new file is correct, it can be promoted to .styled and
							 | 
						||
| 
								 | 
							
								committed to the repository.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The results of the fold will be compared to the corresponding .folded file and if different
							 | 
						||
| 
								 | 
							
								the result will be saved to a .folded.new file for checking.
							 | 
						||
| 
								 | 
							
								So, if x.cxx is the example, its folded form will be checked against x.cxx.folded and a
							 | 
						||
| 
								 | 
							
								x.cxx.folded.new file may be created. The folded.new and .folded files contain the text
							 | 
						||
| 
								 | 
							
								of the original file along with fold information to the left like:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 2 400   0 + --[[ coding:UTF-8
							 | 
						||
| 
								 | 
							
								 0 402   0 | comment ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								There are 4 columns before the file text representing the bits of the fold level:
							 | 
						||
| 
								 | 
							
								[flags (0xF000), level (0x0FFF), other (0xFFFF0000), picture].
							 | 
						||
| 
								 | 
							
								flags: may be 2 for header or 1 for whitespace.
							 | 
						||
| 
								 | 
							
								level: hexadecimal level number starting at 0x400. 'negative' level numbers like 0x3FF
							 | 
						||
| 
								 | 
							
								indicate errors in either the folder or in the input file, such as a C file that starts with #endif.
							 | 
						||
| 
								 | 
							
								other: can be used as the folder wants. Often used to hold the level of the next line.
							 | 
						||
| 
								 | 
							
								picture: gives a rough idea of the fold structure: '|' for level greater than 0x400,
							 | 
						||
| 
								 | 
							
								'+' for header, ' ' otherwise.
							 | 
						||
| 
								 | 
							
								After checking that the .folded.new file is correct, it can be promoted to .folded and
							 | 
						||
| 
								 | 
							
								committed to the repository.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								An interactive file comparison program like WinMerge (https://winmerge.org/) on
							 | 
						||
| 
								 | 
							
								Windows or meld (https://meldmerge.org/) on Linux can help examine differences
							 | 
						||
| 
								 | 
							
								between the .styled and .styled.new files or .folded and .folded.new files.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								On Windows, the scripts/PromoteNew.bat script can be run to promote all .new result
							 | 
						||
| 
								 | 
							
								files to their base names without .new.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Styling and folding tests are first performed on the file as a whole, then the file is lexed
							 | 
						||
| 
								 | 
							
								and folded line-by-line. If there are differences between the whole file and line-by-line
							 | 
						||
| 
								 | 
							
								then a message with 'per-line is different' for styling or 'per-line has different folds' will be
							 | 
						||
| 
								 | 
							
								printed. Problems with line-by-line processing are often caused by local variables in the
							 | 
						||
| 
								 | 
							
								lexer or folder that are incorrectly initialised. Sometimes extra state can be inferred, but it
							 | 
						||
| 
								 | 
							
								may have to be stored between runs (possibly with SetLineState) or the code may have to
							 | 
						||
| 
								 | 
							
								backtrack to a previous safe line - often something like a line that starts with a character
							 | 
						||
| 
								 | 
							
								in the default style.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The SciTE.properties file is similar to properties files used for SciTE but are simpler.
							 | 
						||
| 
								 | 
							
								The lexer to be run is defined with a lexer.{filepatterns} statement like:
							 | 
						||
| 
								 | 
							
									lexer.*.d=d
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Keywords may be defined with keywords settings like:
							 | 
						||
| 
								 | 
							
									keywords.*.cxx;*.c=int char
							 | 
						||
| 
								 | 
							
									keywords2.*.cxx=open
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Substyles and substyle identifiers may be defined with settings like:
							 | 
						||
| 
								 | 
							
									substyles.cpp.11=1
							 | 
						||
| 
								 | 
							
									substylewords.11.1.*.cxx=map string vector
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Other settings are treated as lexer or folder properties and forwarded to the lexer/folder:
							 | 
						||
| 
								 | 
							
									lexer.cpp.track.preprocessor=1
							 | 
						||
| 
								 | 
							
									fold=1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								It is often necessary to set 'fold' in SciTE.properties to cause folding.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Properties can be set for a particular file with an "if $(=" or "match" expression like so:
							 | 
						||
| 
								 | 
							
								if $(= $(FileNameExt);HeaderEOLFill_1.md)
							 | 
						||
| 
								 | 
							
								    lexer.markdown.header.eolfill=1
							 | 
						||
| 
								 | 
							
								match Header*1.md
							 | 
						||
| 
								 | 
							
								    lexer.markdown.header.eolfill=1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								More complex tests with additional configurations of keywords or properties can be performed
							 | 
						||
| 
								 | 
							
								by creating another subdirectory with the different settings in a new SciTE.properties.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								There is some support for running benchmarks on lexers and folders. The properties
							 | 
						||
| 
								 | 
							
								testlexers.repeat.lex and testlexers.repeat.fold specify the number of times example
							 | 
						||
| 
								 | 
							
								documents are lexed or folded. Set to a large number like testlexers.repeat.lex=10000
							 | 
						||
| 
								 | 
							
								then run with a profiler.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								A list of styles used in a lex can be displayed with testlexers.list.styles=1.
							 |