Skip to content

internal.stringTemplates

orciument edited this page Nov 16, 2024 · 1 revision

String templates can be used to specify where variable Content should be placed in a string. They roughly follow the ${VAR} style of template string. A mor comprehensive guide can be found here. Interpolation, If, and For directives are supported.

Warning

  • Logical Operators like && and || are not supported! Only Comparison Operators are implemented. (!= is also supported)
  • You have to leave one whitespace bevor and after the comparison operator
  • The if statement only supports comparison operators, not statements that evaluate to true (a variable with true inside will not work as a condition for an if statement). As a workaround you can check the variable explixitly value == "true"
  • Only one wildcard is allowed per for statement
  • Be careful of unfinished or unclosed tags, these cases are not always handled gracefully
  • automatic whitespace stripping from hardcoded text or variables is not supported
  • You can only access fields on an object, not getters or other methods

Implementation

The parsing of String templates is split into two (or more) parsing steps, all major sections are parsed in the first pass, all specialized parts, like the heads of if and for statements have their own specialized parser. The main parser will only isolate these entire sections and will hand them of to the more specialized parsers. This is done because these sections have their own syntax rules that are completely separate from the rest of the template, e.g.: variables don't need to be prefixed with a $, but all hard coded strings need to be enclosed by ", these rules are completely opposite to the rest of the template. This split in responsibilities removes complexity by not trying to mix both contexts into one class/one (or multiple) functions, but instead making these two discrete steps.

For all major an minor sections the string is first grouped into tokens. Tokens are not much more than tags indicating what this is string of characters means. Tokens are always in a list sorted by there appearance in the string. Tokens are then parsed into statements. Statements are single or multiple Tokens grouped in a logical unit that describes the construct they are a part of. e.g.: A ForStatement contains all information needed to describe and execute a for loop, this includes a list of all statements in the body. So statements are organized in a list of trees.

Tokens

A Token always consists of a type enum, and a string value. The string value is the string that were found to be this token, this can literally the word else for every else token, but can also be the number of an int, or the hard coded text of a string. The kind indicates what kind of major or minor token this is, string, int, var, ...

Major Parser (TemplateParser)

The tokenising is done in the TemplateLexer. It classifies the template string into these tokens:

  • TEXT
  • VAR
  • FOR_HEAD
  • FOR_END
  • IF_HEAD
  • IF_ELSE
  • IF_END This is an example of how the Template parser would tokenise a string:

Hello, %{ if var.name != "test" }'${var.name}'%{ else }unnamed%{ endif }!

color meaning
green strings/text
blue variables
red if head
pink else
lila endif
(while tokenising, %{} and ${} are also stripped, because they are unnecessary now)

the TemplateParser then parses these into Statements.

the TemplateInterpreter then uses the resulting tree to build the final string with the provided variables.

Minor Parsers (If & for)

Tokens:

  • STRING
  • INT
  • DOUBLE
  • BOOLEAN
  • VAR
  • COMPARISON
Clone this wiki locally