Enhanced C#
Language of your choice: library documentation
|
A preprocessor usually inserted between the lexer and parser that inserts "indent", "dedent", and "end-of-line" tokens at appropriate places in a token stream. More...
A preprocessor usually inserted between the lexer and parser that inserts "indent", "dedent", and "end-of-line" tokens at appropriate places in a token stream.
Suppose you use an IndentToken and DedentToken that are equal to the token types you've chosen for { braces }
(e.g. (TokenKind.LBrace and TokenKind.RBrace), the only indent trigger is a colon (:), and you set EolToken to the token type you're using for semicolons. Then the token stream from input such as
will be converted to a token stream equivalent to
That is, a semicolon is added to lines that don't already have one, open braces are inserted right after colons, and semicolons are not added right after opening braces.
If multiple indents occur on a single line, as in
The output will be like this:
Newlines generally represent the end of a statement, while colons mark places where a "child" block is expected. Inside parenthesis, square brackets, or braces, newlines are ignored:
And, inside brackets, indentation is ignored, so this is allowed:
Note that if you don't use brackets, Python 3 doesn't try to figure out if you "really" meant to continue a statement on the next line:
Thus OpenBrackets and CloseBrackets should be ( [ {
and ) ] }
, respectively. IndentType and DedentType should be synthetic Indent and Dedent tokens, since curly braces have a different meaning (they define a dictionary).
In Python, it appears you can't write two "block" statements on one line, as in this example:
You're also not allowed to indent the next line if the block statement on the current line is followed by another statement:
But you can switch style in different branches:
Also, although you can normally separate statements with semicolons:
You are not allowed to write this:
Considering these three facts, I would say that the colon should be classified as an EOL indent trigger (EolIndentTriggers), and the parser should
Now, Python doesn't allow a block statement without a pass
, e.g.:
I'm inclined to treat this as a special case to be detected in the parser. And although you can write a semicolon on a line by itself, you can't write any of these lines:
My interpretation is that a semicolon by itself is treated as a block statement (i.e. illegal in a non-block statement context). Since a semicolon is not treated the same way as a newline, the EolToken should be a special token, not a semicolon.
For more information about LES's indent processing, see LesIndentTokenGenerator .
Properties | |
int[] | AllIndentTriggers [get, set] |
int[] | EolIndentTriggers [get, set] |
Token | EolToken [get, set] |
Gets or sets the prototype token for end-statement (a.k.a. end-of-line) markers, cast to an integer as required by Token. Use null to avoid generating such markers. More... | |
Token | IndentToken [get, set] |
Gets or sets the prototype token for indentation markers. More... | |
Token | DedentToken [get, set] |
Gets or sets the prototype token for unindentation markers. More... | |
Public Member Functions | |
IndentTokenGenerator (ILexer< Token > lexer, int[] allIndentTriggers, Token?eolToken, Token indentToken, Token dedentToken) | |
Initializes the indent detector. More... | |
IndentTokenGenerator (ILexer< Token > lexer, int[] allIndentTriggers, Token?eolToken) | |
override TokenCategory | GetTokenCategory (Token token) |
Protected Member Functions | |
bool | Contains (int[] list, int item) |
override Maybe< Token > | MakeIndentToken (Token indentTrigger, ref Maybe< Token > tokenAfterward, bool newlineAfter) |
override IEnumerator< Token > | MakeDedentToken (Token tokenBeforeDedent, ref Maybe< Token > tokenAfterDedent) |
override Maybe< Token > | MakeEndOfLineToken (Token tokenBeforeNewline, ref Maybe< Token > tokenAfterNewline, int?deltaIndent) |
|
inline |
Initializes the indent detector.
lexer | Original lexer |
allIndentTriggers | A list of all token types that could trigger the insertion of an indentation token. |
eolToken | Prototype token for end-statement markers inserted when newlines are encountered, or null to avoid generating such markers. |
indentToken | Prototype token for indentation markers |
dedentToken | Prototype token for un-indent markers |
|
getset |
Gets or sets the prototype token for unindentation markers.
The StartIndex is updated for each actual token emitted.
|
getset |
Gets or sets the prototype token for end-statement (a.k.a. end-of-line) markers, cast to an integer as required by Token. Use null
to avoid generating such markers.
Note: if the last token on a line has this same type, this class will not generate an extra newline token.
The StartIndex is updated for each actual token emitted.
|
getset |
Gets or sets the prototype token for indentation markers.
The StartIndex is updated for each actual token emitted.