1local info = {
2 version = 1.002,
3 comment = "scintilla lpeg lexer for cpp",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files",
7}
8
9
10
11local P, R, S = lpeg.P, lpeg.R, lpeg.S
12
13local lexer = require("scite-context-lexer")
14local context = lexer.context
15local patterns = context.patterns
16
17local token = lexer.token
18local exact_match = lexer.exact_match
19
20local cpplexer = lexer.new("cpp","scite-context-lexer-cpp")
21local whitespace = cpplexer.whitespace
22
23local keywords = {
24
25 "asm", "auto", "break", "case", "const", "continue", "default", "do", "else",
26 "extern", "false", "for", "goto", "if", "inline", "register", "return",
27 "sizeof", "static", "switch", "true", "typedef", "volatile", "while",
28 "restrict",
29
30 "_Bool", "_Complex", "_Pragma", "_Imaginary",
31 "boolean",
32
33 "catch", "class", "const_cast", "delete", "dynamic_cast", "explicit",
34 "export", "friend", "mutable", "namespace", "new", "operator", "private",
35 "protected", "public", "signals", "slots", "reinterpret_cast",
36 "static_assert", "static_cast", "template", "this", "throw", "try", "typeid",
37 "typename", "using", "virtual"
38}
39
40local datatypes = {
41 "bool", "char", "double", "enum", "float", "int", "long", "short", "signed",
42 "struct", "union", "unsigned", "void"
43}
44
45local macros = {
46 "define", "elif", "else", "endif", "error", "if", "ifdef", "ifndef", "import",
47 "include", "line", "pragma", "undef", "using", "warning"
48}
49
50local luatexs = {
51 "word", "halfword", "quarterword", "scaledwhd", "scaled", "pointer", "glueratio", "strnumber",
52 "dumpstream", "memoryword",
53}
54
55local space = patterns.space
56local any = patterns.any
57local restofline = patterns.restofline
58local startofline = patterns.startofline
59
60local squote = P("'")
61local dquote = P('"')
62local period = P(".")
63local escaped = P("\\") * P(1)
64local slashes = P("//")
65local begincomment = P("/*")
66local endcomment = P("*/")
67local percent = P("%")
68
69local hexadecimal = patterns.hexadecimal
70local decimal = patterns.decimal
71local float = patterns.float
72local integer = P("-")^-1 * (hexadecimal + decimal)
73
74local spacing = token(whitespace, space^1)
75local rest = token("default", any)
76
77local shortcomment = token("comment", slashes * restofline^0)
78local longcomment = token("comment", begincomment * (1-endcomment)^0 * endcomment^-1)
79
80local shortstring = token("quote", dquote)
81 * token("string", (escaped + (1-dquote))^0)
82 * token("quote", dquote)
83 + token("quote", squote)
84 * token("string", (escaped + (1-squote))^0)
85 * token("quote", squote)
86
87local number = token("number", float + integer)
88
89local validword = R("AZ","az","__") * R("AZ","az","__","09")^0
90local identifier = token("default",validword)
91
92local operator = token("special", S("+-*/%^!=<>;:{}[]().&|?~"))
93
94
95
96local p_keywords = exact_match(keywords)
97local p_datatypes = exact_match(datatypes)
98local p_macros = exact_match(macros)
99local p_luatexs = exact_match(luatexs)
100
101local keyword = token("keyword", p_keywords)
102local datatype = token("keyword", p_datatypes)
103local identifier = token("default", validword)
104local luatex = token("command", p_luatexs)
105
106local macro = token("data", #P("#") * startofline * P("#") * S("\t ")^0 * p_macros)
107
108cpplexer._rules = {
109 { "whitespace", spacing },
110 { "keyword", keyword },
111 { "type", datatype },
112 { "luatex", luatex },
113 { "identifier", identifier },
114 { "string", shortstring },
115 { "longcomment", longcomment },
116 { "shortcomment", shortcomment },
117 { "number", number },
118 { "macro", macro },
119 { "operator", operator },
120 { "rest", rest },
121}
122
123local web = lexer.loadluafile("scite-context-lexer-web-snippets")
124
125if web then
126
127 lexer.inform("supporting web snippets in cpp lexer")
128
129 cpplexer._rules_web = {
130 { "whitespace", spacing },
131 { "keyword", keyword },
132 { "type", datatype },
133 { "luatex", luatex },
134 { "identifier", identifier },
135 { "string", shortstring },
136 { "longcomment", longcomment },
137 { "shortcomment", shortcomment },
138 { "web", web.pattern },
139 { "number", number },
140 { "macro", macro },
141 { "operator", operator },
142 { "rest", rest },
143 }
144
145else
146
147 lexer.report("not supporting web snippets in cpp lexer")
148
149 cpplexer._rules_web = {
150 { "whitespace", spacing },
151 { "keyword", keyword },
152 { "type", datatype },
153 { "luatex", luatex },
154 { "identifier", identifier },
155 { "string", shortstring },
156 { "longcomment", longcomment },
157 { "shortcomment", shortcomment },
158 { "number", number },
159 { "macro", macro },
160 { "operator", operator },
161 { "rest", rest },
162 }
163
164end
165
166cpplexer._tokenstyles = context.styleset
167
168cpplexer._foldpattern = P("/*") + P("*/") + S("{}")
169
170cpplexer._foldsymbols = {
171 _patterns = {
172 "[{}]",
173 "/%*",
174 "%*/",
175 },
176
177
178
179
180
181
182
183
184 ["special"] = {
185 ["{"] = 1,
186 ["}"] = -1,
187 },
188 ["comment"] = {
189 ["/*"] = 1,
190 ["*/"] = -1,
191 }
192}
193
194
195
196cpplexer._foldpatterns = nil
197cpplexer._foldsymbols = nil
198
199return cpplexer
200 |