scite-context-lexer-cpp.lua /size: 6101 b    last modification: 2021-10-28 13:49
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-- looks liks the original cpp lexer but web ready (so nothing special here yet)
10
11local P, R, S = lpeg.P, lpeg.R, lpeg.S
12
13local lexers        = require("scite-context-lexer")
14
15local patterns      = lexers.patterns
16local token         = lexers.token
17
18local cpplexer      = lexers.new("cpp","scite-context-lexer-cpp")
19local cppwhitespace = cpplexer.whitespace
20
21local keywords = { -- copied from cpp.lua
22    -- c
23    "asm", "auto", "break", "case", "const", "continue", "default", "do", "else",
24    "extern", "false", "for", "goto", "if", "inline", "register", "return",
25    "sizeof", "static", "switch", "true", "typedef", "volatile", "while",
26    "restrict",
27    -- hm
28    "_Bool", "_Complex", "_Pragma", "_Imaginary",
29    "boolean",
30    -- c++.
31    "catch", "class", "const_cast", "delete", "dynamic_cast", "explicit",
32    "export", "friend", "mutable", "namespace", "new", "operator", "private",
33    "protected", "public", "signals", "slots", "reinterpret_cast",
34    "static_assert", "static_cast", "template", "this", "throw", "try", "typeid",
35    "typename", "using", "virtual"
36}
37
38local datatypes = { -- copied from cpp.lua
39    "bool", "char", "double", "enum", "float", "int", "long", "short", "signed",
40    "struct", "union", "unsigned", "void"
41}
42
43local macros = { -- copied from cpp.lua
44    "define", "elif", "else", "endif", "error", "if", "ifdef", "ifndef", "import",
45    "include", "line", "pragma", "undef", "using", "warning"
46}
47
48local luatexs = {
49    "word", "halfword", "quarterword", "scaledwhd", "scaled", "pointer", "glueratio", "strnumber",
50    "dumpstream", "memoryword",
51}
52
53local space         = patterns.space -- S(" \n\r\t\f\v")
54local any           = patterns.any
55local restofline    = patterns.restofline
56local startofline   = patterns.startofline
57local exactmatch    = patterns.exactmatch
58
59local squote        = P("'")
60local dquote        = P('"')
61local period        = P(".")
62local escaped       = P("\\") * P(1)
63local slashes       = P("//")
64local begincomment  = P("/*")
65local endcomment    = P("*/")
66local percent       = P("%")
67
68local hexadecimal   = patterns.hexadecimal
69local decimal       = patterns.decimal
70local float         = patterns.float
71local integer       = P("-")^-1 * (hexadecimal + decimal) -- also in patterns ?
72
73local spacing       = token(cppwhitespace, space^1)
74local rest          = token("default", any)
75
76local shortcomment  = token("comment", slashes * restofline^0)
77local longcomment   = token("comment", begincomment * (1-endcomment)^0 * endcomment^-1)
78
79local shortstring   = token("quote",  dquote) -- can be shared
80                    * token("string", (escaped + (1-dquote))^0)
81                    * token("quote",  dquote)
82                    + token("quote",  squote)
83                    * token("string", (escaped + (1-squote))^0)
84                    * token("quote",  squote)
85
86local number        = token("number", float + integer)
87
88local validword     = R("AZ","az","__") * R("AZ","az","__","09")^0
89local identifier    = token("default",validword)
90
91local operator      = token("special", S("+-*/%^!=<>;:{}[]().&|?~"))
92
93----- optionalspace = spacing^0
94
95local p_keywords    = exactmatch(keywords)
96local p_datatypes   = exactmatch(datatypes)
97local p_macros      = exactmatch(macros)
98local p_luatexs     = exactmatch(luatexs)
99
100local keyword       = token("keyword", p_keywords)
101local datatype      = token("keyword", p_datatypes)
102local identifier    = token("default", validword)
103local luatex        = token("command", p_luatexs)
104
105local macro         = token("data", #P("#") * startofline * P("#") * S("\t ")^0 * p_macros)
106
107cpplexer.rules = {
108    { "whitespace",   spacing      },
109    { "keyword",      keyword      },
110    { "type",         datatype     },
111    { "luatex",       luatex       },
112    { "identifier",   identifier   },
113    { "string",       shortstring  },
114    { "longcomment",  longcomment  },
115    { "shortcomment", shortcomment },
116    { "number",       number       },
117    { "macro",        macro        },
118    { "operator",     operator     },
119    { "rest",         rest         },
120}
121
122local web = lexers.loadluafile("scite-context-lexer-web-snippets")
123
124if web then
125
126 -- lexers.report("supporting web snippets in cpp lexer")
127
128    cpplexer.rules_web = {
129        { "whitespace",   spacing      },
130        { "keyword",      keyword      },
131        { "type",         datatype     },
132        { "luatex",       luatex       },
133        { "identifier",   identifier   },
134        { "string",       shortstring  },
135        { "longcomment",  longcomment  },
136        { "shortcomment", shortcomment },
137        { "web",          web.pattern  },
138        { "number",       number       },
139        { "macro",        macro        },
140        { "operator",     operator     },
141        { "rest",         rest         },
142    }
143
144else
145
146 -- lexers.report("not supporting web snippets in cpp lexer")
147
148    cpplexer.rules_web = {
149        { "whitespace",   spacing      },
150        { "keyword",      keyword      },
151        { "type",         datatype     },
152        { "luatex",       luatex       },
153        { "identifier",   identifier   },
154        { "string",       shortstring  },
155        { "longcomment",  longcomment  },
156        { "shortcomment", shortcomment },
157        { "number",       number       },
158        { "macro",        macro        },
159        { "operator",     operator     },
160        { "rest",         rest         },
161    }
162
163end
164
165cpplexer.folding = {
166 -- ["region"]    = { ["data"]    =  1 },
167 -- ["endregion"] = { ["data"]    = -1 },
168 -- ["if"]        = { ["data"]    =  1 },
169 -- ["ifdef"]     = { ["data"]    =  1 },
170 -- ["ifndef"]    = { ["data"]    =  1 },
171 -- ["endif"]     = { ["data"]    = -1 },
172    ["{"]         = { ["special"] =  1 },
173    ["}"]         = { ["special"] = -1 },
174    ["/*"]        = { ["comment"] =  1 },
175    ["*/"]        = { ["comment"] = -1 },
176}
177
178return cpplexer
179