Commit Graph

82 Commits

Author SHA1 Message Date
Martin Atkins
5477fecfad zclsyntax: require newlines after block items
Previously we tolerated EOF as an alias for newline, but a file without
a newline at the end is a edge case primarily limited to contrived
examples in unit tests, and requiring it simplifies tasks such as code
generation in zclwrite, since we can always assume that every block item
comes with a built-in line terminator.
2017-06-09 08:19:47 -07:00
Martin Atkins
755fe38505 zclsyntax: peeker pretends single-line comments are newlines
When we're skipping comments but retaining newlines, we need to do some
slight-of-hand because single-line comment tokens contain the newline
that terminates them (for simpler handling of lead doc comments) but our
parsing can be newline-sensitive.

To allow for this, as a special case we transform single-line comment
tokens into newlines when in this situation, thus allowing parser code
to just worry about the newlines and skip over the comments.
2017-06-09 07:19:25 -07:00
Martin Atkins
c88641b147 zclwrite: absorb lead comments into attributes
The native parser's ranges don't include any surrounding comments, so we
need to do a little more work to pick them out of the surrounding token
sequences.

This just takes care of _lead_ comments, which are those that appear as
whole line comments above the item in question. Line comments, which
appear after the item on the same line, will follow in a later commit.
2017-06-08 09:04:27 -07:00
Martin Atkins
34be20cc5d zclsyntax: ScopeTraversalExpr.Value implementation, and tests 2017-06-05 08:02:54 -07:00
Martin Atkins
ace387f5f9 zclsyntax: evaluation of relative traversal and index nodes 2017-06-05 07:41:02 -07:00
Martin Atkins
0266334560 zclsyntax: handle case where functions are not allowed
Previously this would panic.
2017-06-05 07:31:09 -07:00
Martin Atkins
bca573d3d0 zclsyntax: parsing of the index operator
This can either be a traversal or a first-class node depending on whether
the given expression is a literal. This exception is made to allow
applications to conditionally populate only part of a potentially-large
collection if the config is only requesting one or two distinct indices.

In particular, it allows the following to be considered a single traversal
from the scope:

    foo.bar[0].baz
2017-06-05 07:09:04 -07:00
Martin Atkins
8fc5bd5141 zclsyntax: run stringer after other generators
stringer is more sensitive to certain errors than other generators, so
by running it last we give the other generators a chance to get things
straight before we ask stringer to run.
2017-06-05 07:04:26 -07:00
Martin Atkins
b5471b9715 zclsyntax: beginnings of parsing traversal operators
Traversal operators are the operators that can appear after a value
to traverse into the data structure that value represents. So far only
the attribute access operator is implemented.
2017-06-04 18:41:16 -07:00
Martin Atkins
0d0404867c zclsyntax: RelativeTraversalExpr
This is similar to ScopeTraversalExpr, but it traverses relative to the
result of another expression rather than relative to a variable in the
scope.
2017-06-04 18:40:15 -07:00
Martin Atkins
6f2bd0009c zclsyntax: parsing and evaluation for object constructors 2017-06-04 16:14:02 -07:00
Martin Atkins
cac847b163 zclsyntax: separate tokens for assign = and equality test == 2017-06-04 16:00:40 -07:00
Martin Atkins
c3f4694e06 zclsyntax: parsing and evaluation of tuple constructors 2017-06-04 14:22:51 -07:00
Martin Atkins
4488df0cd8 zclsyntax: create comma tokens in the scanner 2017-06-04 14:22:27 -07:00
Martin Atkins
c9c2a2bd16 zclsyntax: Implement the ContextString interface on our Nav
This allows tooling to get a string describing the context of a particular
offset into the file. This is used, for example, to provide context
above the source code snippets in console-printed diagnostic messages.
2017-06-04 09:52:16 -07:00
Martin Atkins
e100bf4723 zclsyntax: generate lexer diagnostics
There are certain tokens that are _never_ valid, so we might as well
catch them early in the Lex... functions rather than having to handle
them in many different contexts within the parser.

Unfortunately for now when such errors occur they tend to be echoed by
more confusing errors coming from the parser, but we'll accept that for
now.
2017-06-04 07:34:26 -07:00
Martin Atkins
c9ac91aa84 Add MissingItemRange to zcl.BodyContent
This allows code that only deals with BodyContent (post-decoding) to
still be able to report on missing items within the associated body while
providing a suitable source location.
2017-06-03 16:46:49 -07:00
Martin Atkins
cad3e7957f zclsyntax: Body.Content and Body.PartialContent 2017-06-03 09:04:16 -07:00
Martin Atkins
da1f9950a6 zclsyntax: Body.JustAttributes implementation 2017-06-03 07:29:48 -07:00
Martin Atkins
aacf36abfd zclsyntax: permit arbitrary newlines inside template interpolations 2017-06-03 06:57:28 -07:00
Martin Atkins
c15eb86349 zclsyntax: require block definitions to end with a newline
Previously we ostensibly allowed block {}block {}, but now we'll reject
that.
2017-06-02 08:19:11 -07:00
Martin Atkins
4d6dbdbb37 zclsyntax: parsing of attributes within bodies 2017-06-02 08:12:33 -07:00
Martin Atkins
a1368a4d4d zclsyntax: parsing of function call expressions 2017-06-02 07:55:03 -07:00
Martin Atkins
e66e6a5f51 zclsyntax: add TokenComma TokenType 2017-06-02 07:40:42 -07:00
Martin Atkins
6052cb9938 zclsyntax: parse expressions in newline-ignoring mode
This applies both two the whole of bare expressions and to any nested
expressions within parentheses. The latter means that an attribute value
can span over multiple lines if it's wrapped in parens:

    foo = (
        1 + 2 + 3 + 4 + 5
    )
2017-06-02 07:26:45 -07:00
Martin Atkins
302487ce0f zclsyntax: template interpolation trimming
The ~ character can be used at the start and end of interpolation
sequences to trim off whitespace in neighboring literals, with the goal
of allowing extra whitespace to be included for readability without
including it in the resulting string.
2017-06-01 08:43:59 -07:00
Martin Atkins
fdfdfc4f3d zclsyntax: scan correctly closing ~} markers
Previously we were failing to return back to template-scanning mode due
to decrementing "braces" too early, causing the remainder of the template
to be scanned as if it were an expression.
2017-06-01 08:36:48 -07:00
Martin Atkins
8004488042 zclsyntax: public-facing ParseTemplate function
This allows calling applications to deal with bare templates, e.g. loaded
from separate files referenced in a main configuration.
2017-06-01 08:10:04 -07:00
Martin Atkins
8532fe32e6 zclsyntax: basic parsing and evaluation of string templates
Control sequences are not yet supported, but interpolation sequences work.
2017-06-01 08:01:12 -07:00
Martin Atkins
ab9bab3578 zclsyntax: parsing of the two unary operators 2017-06-01 07:05:22 -07:00
Martin Atkins
7f27d7b324 zclsyntax: parsing of boolean/null literals and root variable references 2017-06-01 06:56:45 -07:00
Martin Atkins
76d29e4031 zclsyntax: correct spelling of "parenthesis". 2017-06-01 06:42:04 -07:00
Martin Atkins
8f26a22933 zclsyntax: convert condition expr to bool in ConditionalExpr 2017-05-31 19:30:17 -07:00
Martin Atkins
085dff2472 zclsyntax: start of testing expression evaluation 2017-05-31 19:27:16 -07:00
Martin Atkins
3765519c52 zclsyntax: start of parsing expression terms
Just parenthesized expressions and errors so far.
2017-05-31 19:09:11 -07:00
Martin Atkins
9a380c6260 zclsyntax: first pass of parsing binary operations
Not actually tested yet, since it can't be used until parseExpressionTerm
works.
2017-05-31 18:54:54 -07:00
Martin Atkins
2fc14b729a zclsyntax: start of expression parsing
Conditional expression parsing is ostensibly implemented, but since it
depends on the rest of the expression parsers -- not yet implemented --
it cannot be tested in isolation.

Also includes an initial implementation of the conditional expression
node, but this is also not yet tested and so may need further revisions
once we're in a better position to test it.
2017-05-31 08:37:17 -07:00
Martin Atkins
3a0dec45a6 zclsyntax: enum for expression operations
Also includes the binary operator precedence table.
2017-05-31 07:39:23 -07:00
Martin Atkins
effa9a97b5 zclsyntax: add TokenPercent
This was missed on the first pass, and is needed for the modulo operator.
2017-05-31 07:31:49 -07:00
Martin Atkins
d003da232e zclsyntax: decode both quoted and unquoted string literals
This rewrite of decodeQuotedLit, now called decodeStringLit, is able to
handle both cases with a single function, and also now correctly handles
situations where double-$ and double-! are not followed immediately by
a { symbol, and must thus be treated literally.
2017-05-31 07:16:32 -07:00
Martin Atkins
f8bdda5ab9 zclsyntax: decoding of quoted string literal escape sequences 2017-05-30 19:38:31 -07:00
Martin Atkins
f94c89a6a5 zclsyntax: differentiate quoted and unquoted string literals
The context where a string literal was found affects what sort of escaping
it can have, so we need to distinguish these cases so that we will only
look for and handle backslash escapes in quoted strings.
2017-05-30 19:03:25 -07:00
Martin Atkins
284eb635b9 zclsyntax: fix parser infinite loops on certain EOF cases
The recovery functions in particular were not all properly handling EOF,
so they would spin forever looking for the right place to stop.
2017-05-30 18:54:38 -07:00
Martin Atkins
db5167e3d8 zclsyntax: recoverAfterBodyItem implementation
This recovery method attempts to place the peeker directly after the
newline indicating the end of the current body item. It does this by
counting open and close bracketing constructs and then returning when
a newline is encountered with no bracketing constructs open.

It's designed for use in the "header" part of a body item, with no
bracketing constructs open yet. It _might_ work in other situations, but
is likely to end up choosing the wrong end point if used in the middle
of a bracketed expression that itself contains newlines.
2017-05-30 18:42:45 -07:00
Martin Atkins
9348014b2d zclparse: ParseZCL and ParseZCLFile methods
These are the top-level interface to parsing configuration files in the
native zcl syntax, similarly to the existing methods for parsing other
syntaxes.
2017-05-30 08:03:38 -07:00
Martin Atkins
e953e1c18a zclsyntax: parsing of nested blocks within bodies 2017-05-30 07:52:22 -07:00
Martin Atkins
2c90adb9e1 zclsyntax: track whether parser is in recovery mode
The parser has some recovery heuristics but they will not always achieve
the best result. To prevent unsuccessful recovery from causing a cascade
of confusing follow-on errors, we'll track in the parser whether recovery
has been attempted and then the specific sub-parsers can use this to
skip certain "unexpected token type" errors in recovery situations,
assuming instead that an earlier error will cover the problem and that
we just want to bail out quickly.
2017-05-30 07:51:55 -07:00
Martin Atkins
49aa35133f zclsyntax: helper for parsing literal quoted strings
The scanner produces complicated sequences for quoted strings due to the
template language, but sometimes we just want a simple string with no
interpolations.
2017-05-29 19:59:28 -07:00
Martin Atkins
cf3cd7f86d zclsyntax: don't allow quoted strings as attribute names
This will be allowed for object literals, but attributes are treated
differently to reinforce the fact that they have a predefined structure.
2017-05-29 19:58:45 -07:00
Martin Atkins
954939b49f zclsyntax: initial pass at body parsing
Only able to parse empty bodies so far.
2017-05-29 19:28:10 -07:00