During this document, the following code snippet will be used.
on chat:
send "hi"
if true:
send "hi 2"
-
Structural Parsing - Node Parsing
-
Split Parsing - Deferred Parsing
Structural parsing is the first step in the parsing process.
We take the file contents and split it by line. Then, for each line, we compute indentation sizes and separate comments from the actual code.
Resulting structure when going through this parsing step:
on chat: | SkriptNode(lineNumber=0, indentations=[], content='on chat:', comment='', isSectionNode=true)
|----send "hi" | SkriptNode(lineNumber=1, indentations=[NodeIndentationData(type=SPACE, amount=4)], content='send "hi"', comment='', isSectionNode=false)
|----if true: | SkriptNode(lineNumber=2, indentations=[NodeIndentationData(type=SPACE, amount=4)], content='if true:', comment='', isSectionNode=true)
|---send "hi 2" | SkriptNode(lineNumber=3, indentations=[NodeIndentationData(type=SPACE, amount=8)], content='send "hi 2"', comment='', isSectionNode=false)"
Split parsing is a special kind of parsing.
Basically, we take all Skript patterns and only match optional, literal and regex groups.
Doing this will allow us to insert "variable placeholders" where the remaining expressions will be parsed and matched.
Parsing up to this phase will allow us to provide some code inspections (things like "Event cannot be cancelled", "Useless stop statement", "Dead Code")
Given the following pattern:
(message|send [message[s]]) %strings% [to %commandsenders%]
And given this code expression snippet:
send "hi"
Will result in the following pattern-match result:
[
Literal(content='send'),
Whitespace(content=' '),
Unknown(content='"hi"')
]
Although we only have partially matched this pattern, we still have enough information to infer that this is EffMessage
. During the next step, we can then match/parse the remaining information without having to re-match the entire snippet.