Skip to content

Instantly share code, notes, and snippets.

@zach-klippenstein
Last active December 15, 2015 16:09
Show Gist options
  • Save zach-klippenstein/5287318 to your computer and use it in GitHub Desktop.
Save zach-klippenstein/5287318 to your computer and use it in GitHub Desktop.
SystemTap language grammer for Sublime Text 2

(Unfinished) SystemTap language grammer for Sublime Text 2 (and possibly TextMate, although I don't have a copy lying around to test with). This grammar is very unfinished, and probably buggy. This is my first attempt at creating a grammar, and I've just been doing some simple SystemTap development for a school assignment, and was getting tired of staring at plain white text. If you're more experienced or just end up tweaking this, please feel free to send me a pull request!

If there's enough interest, I could throw it into a full package in a full repo.

History

v1.0

Copied a bunch of stuff from the default C grammar.

  • string escapes/format codes
  • better commenting
  • blocks

Also:

  • more operators
  • a bunch more system functions
  • function types

Install instructions

  1. Save SystemTap.tmLanguage in a package directory (e.g. ~/Library/Application Support/Sublime Text 2/Packages/User)
  2. Done.

Build instructions

  1. Install the AAAPackageDev package
  2. Save SystemTap.JSON-tmLanguage in a package directory(e.g. ~/Library/Application Support/Sublime Text 2/Packages/User), and open it
  3. Select Tools—>Build System—>JSON to Property List
  4. Build

Alternatively, use AAAPackageDev to create a new Syntax Definition, and paste away.

If you make any changes, please edit the JSON and generate the XML, and commit both.

{ "name": "SystemTap",
"scopeName": "source.stp",
"fileTypes": ["stp"],
"firstLineMatch": "^#!\\s+(/.+)*\\s*stap",
"repository": {
"access": {
"match": "\\.[a-zA-Z_][a-zA-Z_0-9]*\\b(?!\\s*\\()",
"name": "variable.other.dot-access.stp"
},
"block": {
"begin": "\\{",
"end": "\\}",
"name": "meta.block.stp",
"patterns": [
{
"include": "#block_innards"
}
]
},
"block_innards": {
"patterns": [
{
"include": "#access"
},
{
"captures": {
"1": {
"name": "variable.other.c"
},
"2": {
"name": "punctuation.definition.parameters.stp"
}
},
"match": "(?x)\n\t\t\t (?x)\n\t\t\t(?:\n\t\t\t (?: (?= \\s ) (?<!else|new|return) (?<=\\w)\\s+ # or word + space before name\n\t\t\t )\n\t\t\t)\n\t\t\t(\n\t\t\t\t(?: [A-Za-z_][A-Za-z0-9_]*+ | :: )++ | # actual name\n\t\t\t\t(?: (?<=operator) (?: [-*&<>=+!]+ | \\(\\) | \\[\\] ) )? # if it is a C++ operator\n\t\t\t)\n\t\t\t \\s*(\\()",
"name": "meta.initialization.stp"
},
{
"include": "#block"
},
{
"include": "$base"
}
]
},
"comments": {
"patterns": [
{
"captures": {
"1": {
"name": "meta.toc-list.banner.block.stp"
}
},
"match": "^/\\* =(\\s*.*?)\\s*= \\*/$\\n?",
"name": "comment.block.stp"
},
{
"begin": "/\\*",
"captures": {
"0": {
"name": "punctuation.definition.comment.stp"
}
},
"end": "\\*/",
"name": "comment.block.stp"
},
{
"match": "\\*/.*\\n",
"name": "invalid.illegal.stray-comment-end.stp"
},
{
"captures": {
"1": {
"name": "meta.toc-list.banner.line.stp"
}
},
"match": "^// =(\\s*.*?)\\s*=\\s*$\\n?",
"name": "comment.line.banner.stp"
},
{
"begin": "//",
"beginCaptures": {
"0": {
"name": "punctuation.definition.comment.stp"
}
},
"end": "$\\n?",
"name": "comment.line.double-slash.stp",
"patterns": [
{
"match": "(?>\\\\\\s*\\n)",
"name": "punctuation.separator.continuation.stp"
}
]
},
{
"begin": "#",
"beginCaptures": {
"0": {
"name": "punctuation.definition.comment.stp"
}
},
"end": "$\\n?",
"name": "comment.line.hash.stp",
"patterns": [
{
"match": "(?>\\\\\\s*\\n)",
"name": "punctuation.separator.continuation.stp"
}
]
}
]
},
"parens": {
"begin": "\\(",
"end": "\\)",
"name": "meta.parens.stp",
"patterns": [
{
"include": "$base"
}
]
},
"string_escaped_char": {
"patterns": [
{
"match": "\\\\(\\\\|[abefnprtv'\"?]|[0-3]\\d{,2}|[4-7]\\d?|x[a-fA-F0-9]{,2}|u[a-fA-F0-9]{,4}|U[a-fA-F0-9]{,8})",
"name": "constant.character.escape.stp"
},
{
"match": "\\\\.",
"name": "invalid.illegal.unknown-escape.stp"
}
]
},
"string_placeholder": {
"patterns": [
{
"match": "(?x)%\n \t\t\t\t\t\t(\\d+\\$)? # field (argument #)\n \t\t\t\t\t\t[#0\\- +']* # flags\n \t\t\t\t\t\t[,;:_]? # separator character (AltiVec)\n \t\t\t\t\t\t((-?\\d+)|\\*(-?\\d+\\$)?)? # minimum field width\n \t\t\t\t\t\t(\\.((-?\\d+)|\\*(-?\\d+\\$)?)?)? # precision\n \t\t\t\t\t\t(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)? # length modifier\n \t\t\t\t\t\t[diouxXDOUeEfFgGaACcSspn%] # conversion type\n \t\t\t\t\t",
"name": "constant.other.placeholder.stp"
},
{
"match": "%",
"name": "invalid.illegal.placeholder.stp"
}
]
}
},
"patterns": [
{
"include": "#comments"
},
{ "match": "<<<|[=+\\-*/!&|^?:<>]",
"name": "keyword.operator.stp"
},
{
"begin": "\"",
"beginCaptures": {
"0": {
"name": "punctuation.definition.string.begin.stp"
}
},
"end": "\"",
"endCaptures": {
"0": {
"name": "punctuation.definition.string.end.stp"
}
},
"name": "string.quoted.double.stp",
"patterns": [
{
"include": "#string_escaped_char"
},
{
"include": "#string_placeholder"
}
]
},
{
"begin": "'",
"beginCaptures": {
"0": {
"name": "punctuation.definition.string.begin.stp"
}
},
"end": "'",
"endCaptures": {
"0": {
"name": "punctuation.definition.string.end.stp"
}
},
"name": "string.quoted.single.stp",
"patterns": [
{
"include": "#string_escaped_char"
}
]
},
{ "match": "\\b(if|else|foreach|in|limit|while|delete)\\b",
"name": "keyword.control.stp"
},
{ "match": "@([A-Za-z0-9_]*)",
"name": "support.function.stp"
},
{ "match": "\\b(tid|pid|printf?|gettimeofday_u?s|ctime|(user|kernel)_(char|short|long|int|string(_n)?)|target|execname)\\b",
"name": "support.function.stp"
},
{ "match": "\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b",
"name": "constant.numeric.stp"
},
{ "match": "\\$([A-Za-z][A-Za-z0-9_]*)",
"name": "support.variable.stp"
},
{ "match": "(global)\\s+(([A-Za-z][A-Za-z0-9_]*),?)+",
"name": "meta.variable.stp",
"captures": {
"1": { "name": "storage.modifier.stp" },
"3": { "name": "variable.stp" }
}
},
{ "match": "^\\s*(probe)",
"name": "meta.entity.function.stp",
"captures": {
"1": { "name": "storage.type.stp" }
}
},
{ "match": "^\\s*(function)\\s+([a-zA-Z0-9_]+)(:([a-z]+))?",
"name": "meta.entity.function.stp",
"captures": {
"1": { "name": "storage.type.stp" },
"2": { "name": "entity.function.name.stp" },
"4": { "name": "storage.type.stp" }
}
},
{
"include": "#block"
}
],
"uuid": "472cfceb-6d0c-4d64-af70-d5b59ce45471"
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>fileTypes</key>
<array>
<string>stp</string>
</array>
<key>firstLineMatch</key>
<string>^#!\s+(/.+)*\s*stap</string>
<key>name</key>
<string>SystemTap</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#comments</string>
</dict>
<dict>
<key>match</key>
<string>&lt;&lt;&lt;|[=+\-*/!&amp;|^?:&lt;&gt;]</string>
<key>name</key>
<string>keyword.operator.stp</string>
</dict>
<dict>
<key>begin</key>
<string>"</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.stp</string>
</dict>
</dict>
<key>end</key>
<string>"</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.stp</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.double.stp</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#string_escaped_char</string>
</dict>
<dict>
<key>include</key>
<string>#string_placeholder</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>'</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.stp</string>
</dict>
</dict>
<key>end</key>
<string>'</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.stp</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.single.stp</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#string_escaped_char</string>
</dict>
</array>
</dict>
<dict>
<key>match</key>
<string>\b(if|else|foreach|in|limit|while|delete)\b</string>
<key>name</key>
<string>keyword.control.stp</string>
</dict>
<dict>
<key>match</key>
<string>@([A-Za-z0-9_]*)</string>
<key>name</key>
<string>support.function.stp</string>
</dict>
<dict>
<key>match</key>
<string>\b(tid|pid|printf?|gettimeofday_u?s|ctime|(user|kernel)_(char|short|long|int|string(_n)?)|target|execname)\b</string>
<key>name</key>
<string>support.function.stp</string>
</dict>
<dict>
<key>match</key>
<string>\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\b</string>
<key>name</key>
<string>constant.numeric.stp</string>
</dict>
<dict>
<key>match</key>
<string>\$([A-Za-z][A-Za-z0-9_]*)</string>
<key>name</key>
<string>support.variable.stp</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>storage.modifier.stp</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>variable.stp</string>
</dict>
</dict>
<key>match</key>
<string>(global)\s+(([A-Za-z][A-Za-z0-9_]*),?)+</string>
<key>name</key>
<string>meta.variable.stp</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>storage.type.stp</string>
</dict>
</dict>
<key>match</key>
<string>^\s*(probe)</string>
<key>name</key>
<string>meta.entity.function.stp</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>storage.type.stp</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.function.name.stp</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>storage.type.stp</string>
</dict>
</dict>
<key>match</key>
<string>^\s*(function)\s+([a-zA-Z0-9_]+)(:([a-z]+))?</string>
<key>name</key>
<string>meta.entity.function.stp</string>
</dict>
<dict>
<key>include</key>
<string>#block</string>
</dict>
</array>
<key>repository</key>
<dict>
<key>access</key>
<dict>
<key>match</key>
<string>\.[a-zA-Z_][a-zA-Z_0-9]*\b(?!\s*\()</string>
<key>name</key>
<string>variable.other.dot-access.stp</string>
</dict>
<key>block</key>
<dict>
<key>begin</key>
<string>\{</string>
<key>end</key>
<string>\}</string>
<key>name</key>
<string>meta.block.stp</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#block_innards</string>
</dict>
</array>
</dict>
<key>block_innards</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#access</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>variable.other.c</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.parameters.stp</string>
</dict>
</dict>
<key>match</key>
<string>(?x)
(?x)
(?:
(?: (?= \s ) (?&lt;!else|new|return) (?&lt;=\w)\s+ # or word + space before name
)
)
(
(?: [A-Za-z_][A-Za-z0-9_]*+ | :: )++ | # actual name
(?: (?&lt;=operator) (?: [-*&amp;&lt;&gt;=+!]+ | \(\) | \[\] ) )? # if it is a C++ operator
)
\s*(\()</string>
<key>name</key>
<string>meta.initialization.stp</string>
</dict>
<dict>
<key>include</key>
<string>#block</string>
</dict>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
<key>comments</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>meta.toc-list.banner.block.stp</string>
</dict>
</dict>
<key>match</key>
<string>^/\* =(\s*.*?)\s*= \*/$\n?</string>
<key>name</key>
<string>comment.block.stp</string>
</dict>
<dict>
<key>begin</key>
<string>/\*</string>
<key>captures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.comment.stp</string>
</dict>
</dict>
<key>end</key>
<string>\*/</string>
<key>name</key>
<string>comment.block.stp</string>
</dict>
<dict>
<key>match</key>
<string>\*/.*\n</string>
<key>name</key>
<string>invalid.illegal.stray-comment-end.stp</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>meta.toc-list.banner.line.stp</string>
</dict>
</dict>
<key>match</key>
<string>^// =(\s*.*?)\s*=\s*$\n?</string>
<key>name</key>
<string>comment.line.banner.stp</string>
</dict>
<dict>
<key>begin</key>
<string>//</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.comment.stp</string>
</dict>
</dict>
<key>end</key>
<string>$\n?</string>
<key>name</key>
<string>comment.line.double-slash.stp</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(?&gt;\\\s*\n)</string>
<key>name</key>
<string>punctuation.separator.continuation.stp</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>#</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.comment.stp</string>
</dict>
</dict>
<key>end</key>
<string>$\n?</string>
<key>name</key>
<string>comment.line.hash.stp</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(?&gt;\\\s*\n)</string>
<key>name</key>
<string>punctuation.separator.continuation.stp</string>
</dict>
</array>
</dict>
</array>
</dict>
<key>parens</key>
<dict>
<key>begin</key>
<string>\(</string>
<key>end</key>
<string>\)</string>
<key>name</key>
<string>meta.parens.stp</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
<key>string_escaped_char</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\\(\\|[abefnprtv'"?]|[0-3]\d{,2}|[4-7]\d?|x[a-fA-F0-9]{,2}|u[a-fA-F0-9]{,4}|U[a-fA-F0-9]{,8})</string>
<key>name</key>
<string>constant.character.escape.stp</string>
</dict>
<dict>
<key>match</key>
<string>\\.</string>
<key>name</key>
<string>invalid.illegal.unknown-escape.stp</string>
</dict>
</array>
</dict>
<key>string_placeholder</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(?x)%
(\d+\$)? # field (argument #)
[#0\- +']* # flags
[,;:_]? # separator character (AltiVec)
((-?\d+)|\*(-?\d+\$)?)? # minimum field width
(\.((-?\d+)|\*(-?\d+\$)?)?)? # precision
(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)? # length modifier
[diouxXDOUeEfFgGaACcSspn%] # conversion type
</string>
<key>name</key>
<string>constant.other.placeholder.stp</string>
</dict>
<dict>
<key>match</key>
<string>%</string>
<key>name</key>
<string>invalid.illegal.placeholder.stp</string>
</dict>
</array>
</dict>
</dict>
<key>scopeName</key>
<string>source.stp</string>
<key>uuid</key>
<string>472cfceb-6d0c-4d64-af70-d5b59ce45471</string>
</dict>
</plist>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment