1" Vim syntax file
2" Language:	Lex and Flex
3" Maintainer:	Charles E. Campbell <NcampObell@SdrPchip.AorgM-NOSPAM>
4" Contributor:	Robert A. van Engelen <engelen@acm.org>
5" Last Change:	Apr 24, 2020
6" Version:	18
7
8" quit when a syntax file was already loaded
9if exists("b:current_syntax")
10  finish
11endif
12
13" Read the C++ syntax to start with
14let s:Cpath= fnameescape(expand("<sfile>:p:h")."/cpp.vim")
15if !filereadable(s:Cpath)
16 for s:Cpath in split(globpath(&rtp,"syntax/cpp.vim"),"\n")
17  if filereadable(fnameescape(s:Cpath))
18   let s:Cpath= fnameescape(s:Cpath)
19   break
20  endif
21 endfor
22endif
23exe "syn include @lexCcode ".s:Cpath
24
25" --- ========= ---
26" --- Lex stuff ---
27" --- ========= ---
28
29" Definitions
30" %%
31" Rules
32" %%
33" User Code
34"
35" --- ======= ---
36" --- Example ---
37" --- ======= ---
38"
39"   // this is a valid lex file
40"   // indented initial code block
41"   #include <stdlib.h>
42" %{
43" // initial code block
44" #include <stdio.h>
45" const char *sep = "";
46" %}
47" %option outfile="scanner.c" noyywrap nodefault
48" %x COMMENT
49" id      [A-Za-z_][A-Za-z0-9_]*
50" %%
51"   // indented initial action code block
52"   printf("BEGIN");
53" {id}    printf("%s%s", sep, yytext); sep = "";
54" .       |
55" \n      { sep = "\n"; }
56" "/*"    { BEGIN COMMENT; }
57" "//".*  { }
58" <COMMENT>{
59" "*/"    { BEGIN INITIAL; }
60" .|\n
61" }
62" <*><<EOF>> { // end of file
63"              printf("\nEND\n");
64"              yyterminate();
65"            }
66" %%
67" void scan()
68" {
69"   while (yylex())
70"     continue;
71" }
72" /* main program */
73" int main()
74" {
75"   scan();
76" }
77
78" Definitions Section with initial code blocks, abbreviations, options, states
79if has("folding")
80 syn region lexAbbrvBlock	fold	start="^\S"	end="^\ze%%"	skipnl	nextgroup=lexPatBlock	contains=lexOptions,lexAbbrv,lexInitialCodeBlock,lexInclude,lexAbbrvComment,lexStartState
81else
82 syn region lexAbbrvBlock		start="^\S"	end="^\ze%%"	skipnl	nextgroup=lexPatBlock	contains=lexOptions,lexAbbrv,lexInitialCodeBlock,lexInclude,lexAbbrvComment,lexStartState
83endif
84syn match  lexOptions		"^%\a\+\(\s.*\|[^{]*\)$"				contains=lexOptionsEq,lexPatString,lexSlashQuote,lexBrace,lexSlashBrace
85syn match  lexOptionsEq		"="					skipwhite	contained
86syn match  lexAbbrv		"^\I\i*\s"me=e-1			skipwhite	contained	nextgroup=lexAbbrvPat
87syn match  lexAbbrvPat		"\s\S.*$"lc=1						contained	contains=lexPatAbbrv,lexPatString,lexSlashQuote,lexBrace,lexSlashBrace	nextgroup=lexAbbrv,lexInclude
88syn match  lexStartState	"^%\(xs\?\|s\)\(t\(a\(t\(e\?\)\?\)\?\)\?\)\?\(\s\+\I\i*\)\+\s*$"	contained	contains=lexStartStateCmd
89syn match  lexStartStateCmd	'^%\(xs\?\|s\)\(t\(a\(t\(e\?\)\?\)\?\)\?\)\?'	contained
90if has("folding")
91 syn region lexInitialCodeBlock	fold				start="^\s\+"	end="^\S"me=e-1			contains=@lexCcode
92 syn region lexInclude		fold	matchgroup=lexSep	start="^%\a*{"	end="^%\?}"	contained	contains=@lexCcode,lexCFunctions
93 syn region lexAbbrvComment	fold				start="^\s*//"	end="$"		contains=@Spell
94 syn region lexAbbrvComment	fold				start="^\s*/\*"	end="\*/"	contains=@Spell
95else
96 syn region lexInitialCodeBlock					start="^\s\+"	end="^\S"me=e-1			contains=@lexCcode
97 syn region lexInclude			matchgroup=lexSep	start="^%\a*{"	end="^%\?}"	contained	contains=@lexCcode,lexCFunctions
98 syn region lexAbbrvComment					start="^\s*//"	end="$"		contains=@Spell
99 syn region lexAbbrvComment					start="^\s*/\*"	end="\*/"	contains=@Spell
100endif
101
102" Rules Section with patterns and actions
103if has("folding")
104 syn region lexPatBlock		fold	matchgroup=Todo		start="^%%"	matchgroup=Todo		end="^\ze%%"	skipnl	skipwhite	nextgroup=lexFinalCodeBlock	contains=lexPatTag,lexPatTagZone,lexPatComment,lexPat,lexPatSep,lexPatInclude
105 syn region lexPat		fold				start="\S"	skip="\\\\\|\\\s"	end="\ze\(\s*$\|\s\+\(\h\|{\W\|{$\|[-+*]\|//\|/\*\)\)"	skipwhite	contained nextgroup=lexMorePat,lexPatSep,lexPatEnd	contains=lexPatTag,lexPatString,lexSlashQuote,lexPatAbbrv,lexBrace,lexSlashBrace
106 syn region lexPatInclude	fold	matchgroup=lexSep	start="^%{"	end="^%}"	contained	contains=@lexCcode
107 syn region lexBrace		fold	matchgroup=Character	start="\["	skip="\\.\|\[:\a\+:\]\|\[\.\a\+\.\]\|\[=.=\]"	end="\]"	contained
108 syn region lexPatString	fold	matchgroup=String	start=+"+	skip=+\\\\\|\\"+	matchgroup=String	end=+"+	contained
109else
110 syn region lexPatBlock			matchgroup=Todo		start="^%%"	matchgroup=Todo		end="^\ze%%"	skipnl	skipwhite	nextgroup=lexFinalCodeBlock	contains=lexPatTag,lexPatTagZone,lexPatComment,lexPat,lexPatSep,lexPatInclude
111 syn region lexPat						start="\S"	skip="\\\\\|\\\s"	end="\ze\(\s*$\|\s\+\(\h\|{\W\|{$\|[-+*]\|//\|/\*\)\)"	skipwhite	contained nextgroup=lexMorePat,lexPatSep,lexPatEnd	contains=lexPatTag,lexPatString,lexSlashQuote,lexPatAbbrv,lexBrace,lexSlashBrace
112 syn region lexPatInclude		matchgroup=lexSep	start="^%{"	end="^%}"	contained	contains=@lexCcode
113 syn region lexBrace			matchgroup=Character	start="\["	skip="\\.\|\[:\a\+:\]\|\[\.\a\+\.\]\|\[=.=\]"	end="\]"	contained
114 syn region lexPatString		matchgroup=String	start=+"+	skip=+\\\\\|\\"+	matchgroup=String	end=+"+	contained
115endif
116syn match  lexPatAbbrv		"{\I\i*}"hs=s+1,he=e-1					contained
117syn match  lexPatTag		"^<\^\?\(\I\i*\|\*\)\(,\^\?\(\I\i*\|\*\)\)*>"		contained	nextgroup=lexPat,lexMorePat,lexPatSep,lexPatEnd
118syn match  lexPatTagZone	"^<\^\?\(\I\i*\|\*\)\(,\^\?\(\I\i*\|\*\)\)*>\s*{$"me=e-1	contained	nextgroup=lexPatTagZoneStart
119
120if has("folding")
121 syn region lexPatTagZoneStart	fold	matchgroup=lexPatTag	start='{$'	end='^}'	skipnl	skipwhite	contained	contains=lexPatTag,lexPatTagZone,lexPatComment,lexPat,lexPatSep,lexPatInclude
122 syn region lexPatComment	fold	start="//"	end="$"		skipnl	contained	contains=cTodo	skipwhite	nextgroup=lexPatComment,lexPat,@Spell
123 syn region lexPatComment	fold	start="/\*"	end="\*/"	skipnl	contained	contains=cTodo	skipwhite	nextgroup=lexPatComment,lexPat,@Spell
124else
125 syn region lexPatTagZoneStart		matchgroup=lexPatTag		start='{'	end='^}'	skipnl	skipwhite	contained	contains=lexPatTag,lexPatTagZone,lexPatComment,lexPat,lexPatSep,lexPatInclude
126 syn region lexPatComment		start="//"	end="$"		skipnl	contained	contains=cTodo	skipwhite	nextgroup=lexPatComment,lexPat,@Spell
127 syn region lexPatComment		start="/\*"	end="\*/"	skipnl	contained	contains=cTodo	skipwhite	nextgroup=lexPatComment,lexPat,@Spell
128endif
129syn match  lexPatEnd		"\s*$"				skipnl	contained
130syn match  lexPatCodeLine	"[^{\[].*"				contained	contains=@lexCcode,lexCFunctions
131syn match  lexMorePat		"\s*|\s*$"			skipnl	contained	nextgroup=lexPat,lexPatTag,lexPatComment
132syn match  lexPatSep		"\s\+"					contained	nextgroup=lexMorePat,lexPatCode,lexPatCodeLine
133syn match  lexSlashQuote	+\(\\\\\)*\\"+				contained
134syn match  lexSlashBrace	+\(\\\\\)*\\\[+				contained
135if has("folding")
136 syn region lexPatCode		fold	matchgroup=Delimiter	start="{"	end="}"	skipnl	contained	contains=@lexCcode,lexCFunctions
137else
138 syn region lexPatCode			matchgroup=Delimiter	start="{"	end="}"	skipnl	contained	contains=@lexCcode,lexCFunctions
139endif
140
141" User Code Section with final code block
142syn region lexFinalCodeBlock	matchgroup=Todo	start="^%%"	end="\%$"	contained	contains=@lexCcode
143
144" Lex macros which may appear in C/C++ code blocks
145syn keyword lexCFunctions	BEGIN	ECHO	REJECT	yytext	YYText	yyleng	YYLeng	yymore	yyless	yywrap	yylook
146syn keyword lexCFunctions	yyrestart	yyterminate	yylineno	yycolumno	yyin	yyout
147syn keyword lexCFunctions	input	unput	output		winput		wunput		woutput
148syn keyword lexCFunctions	yyinput	yyunput	yyoutput	yywinput	yywunput	yywoutput
149
150" <c.vim> includes several ALLBUTs; these have to be treated so as to exclude lex* groups
151syn cluster cParenGroup		add=lex.*
152syn cluster cDefineGroup	add=lex.*
153syn cluster cPreProcGroup	add=lex.*
154syn cluster cMultiGroup		add=lex.*
155
156" Synchronization
157syn sync clear
158syn sync minlines=500
159syn sync match lexSyncPat	grouphere  lexPatBlock	"^%[a-zA-Z]"
160syn sync match lexSyncPat	groupthere lexPatBlock	"^<$"
161syn sync match lexSyncPat	groupthere lexPatBlock	"^%%"
162
163" The default highlighting.
164if !exists("skip_lex_syntax_inits")
165 hi def link lexAbbrvComment	lexPatComment
166 hi def link lexAbbrvPat	lexPat
167 hi def link lexAbbrv		Special
168 hi def link lexBrace		lexPat
169 hi def link lexCFunctions	PreProc
170 hi def link lexMorePat		Special
171 hi def link lexOptions		PreProc
172 hi def link lexOptionsEq	Operator
173 hi def link lexPatComment	Comment
174 hi def link lexPat		Function
175 hi def link lexPatString	lexPat
176 hi def link lexPatAbbrv	Special
177 hi def link lexPatTag		Statement
178 hi def link lexPatTagZone	lexPatTag
179 hi def link lexSep		Delimiter
180 hi def link lexSlashQuote	lexPat
181 hi def link lexSlashBrace	lexPat
182 hi def link lexStartState	lexPatTag
183 hi def link lexStartStateCmd	Special
184endif
185
186let b:current_syntax = "lex"
187
188" vim:ts=8
189