Commit Graph

130 Commits

Author SHA1 Message Date
Martin Atkins
1517231d71 build: stop running Travis-CI test run on Go 1.7.x 2017-06-02 08:27:20 -07:00
Martin Atkins
5522e0c8d0 build: capture code coverage stats during Travis-CI run
The results are uploaded to codecov.io to create readable reports.
2017-06-02 08:27:20 -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
57d8ff0c1b json: update tokentype_string for recent new token types 2017-05-30 19:01:40 -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
Martin Atkins
14d256467a zclsyntax: peeker methods to get next and previous token ranges 2017-05-29 19:01:37 -07:00
Martin Atkins
23cb83ef3e zclsyntax: "peeker" helper
This will make it easier for the parser to walk through the token sequence
with one token of lookahead, maintaining state of where we've got to and
also allowing us to switch into and out of the newline-sensitive mode
as we transition to and from newline-sensitive constructs.
2017-05-29 18:09:58 -07:00
Martin Atkins
1a6dfffc4a zclsyntax: Stub public interface for parsing
Mirroring the Lex... triplet of functions, callers here can choose to
parse in one of three modes:

- ParseConfig is the main entry point and parses what we might consider
  a whole config file.

- ParseExpression parses a sequence as an isolated expression, which
  may be useful in implementing a REPL to inspect configuration or
  application state.

- ParseTemplate parses a sequence as an isolated template, which may be
  useful in parsing external files as templates, for situations where the
  input is too large to be conveniently embedded within configuration.
2017-05-29 17:19:23 -07:00
Martin Atkins
476e2c127e zclwrite: convert zclsyntax tokens into zclwrite tokens
In zclwrite we throw away the absolute source position information and
instead just retain the number of spaces before each token. This different
model allows us to rewrite parts of the token sequence without needing
to re-adjust all of the positions, and it also allows us to do simple
indentation and spacing adjustments just by walking through the token
list and adjusting these numbers.
2017-05-29 16:59:20 -07:00
Martin Atkins
865a5d8831 zclsyntax: public interface to the scanner
This LexConfig, LexExpression and LexTemplate set of functions allow
outside callers to use the scanner in isolation, skipping the parser.
This may be useful for use-cases such as syntax highlighting, separate
parsers (such as the one in zclwrite), and so forth. Most callers should
use the parser (once implemented) though, to get a semantic AST.
2017-05-29 16:17:07 -07:00
Martin Atkins
3a567abb51 zclwrite: stub of zcl code generation package
This uses a separate, lower-level AST than the parser so that it can
retain the raw tokens and make surgical changes. As a consequence it
has much less semantic detail than the parser AST, and in particular
doesn't represent the structure of expressions except to retain variable
references to enable global rename operations.
2017-05-29 16:05:34 -07:00
Martin Atkins
7ac858e3f5 zclsyntax: scanning of bare (top-level) templates
This alternative scanning mode makes the scanner start in template
context rather than normal context. This will be later used by the parser
to allow parsing of standalone templates that aren't embedded inside a
zcl configuration file.
2017-05-29 09:42:20 -07:00
Martin Atkins
f1c91b8eea zclsyntax: detect newlines during scanning
This is important because our syntax for objects uses newlines as the
separator between items, so this is the only signal we'll get that a
given item has ended and another is beginning.
2017-05-29 09:25:21 -07:00
Martin Atkins
861d0a1b4e zclsyntax: scanning of comments 2017-05-29 09:13:35 -07:00
Martin Atkins
2551856d22 zclsyntax: heredoc support in the scanner 2017-05-29 08:55:53 -07:00
Martin Atkins
4a939a2b46 zclsyntax: allow scanner to support multiple modes
A scanner "mode" decides which state it starts in, allowing us to start
in template mode for parsing top-level templates. However, currently the
only mode implemented is "normal" mode, which is the behavior we had
before.
2017-05-28 15:44:22 -07:00
Martin Atkins
da874ba0ff zclsyntax: disallow newlines in string templates
Heredocs will deal with the multiline string case once implemented.
2017-05-28 15:35:55 -07:00
Martin Atkins
18e45ec05c zclsyntax: scanner support of string templates
This requires some extra state-keeping because we allow templates to be
nested inside templates. This takes us outside of the world of regular
languages, but we accept that here because it makes things easier to
deal with down the line in the parser.

The methodology is to keep track of how many braces are open at a given
time and then, when a nested template interpolation begins, record the
current brace level. Then, when a closing brace is encountered, if its
nesting level is at the top of the stack then we pop off the stack and
return to "main" parsing mode.

Ragel's existing idea of calling and returning from machines is important
here too. As this currently stands this is not actually needed, but once
heredocs are in play we will have two possible places to return to at
the end of an interpolation sequence, so the state return stack maintained
by Ragel will determine whether to return to string mode or heredoc mode.
2017-05-28 15:33:01 -07:00
Martin Atkins
c50317a2e0 zclsyntax: scan multi-character punctuation tokens 2017-05-28 09:40:58 -07:00
Martin Atkins
bb87c7a0f9 zclsyntax: heredoc to be separate start/end tokens
Just as we have OQuote and CQuote, we need the same for heredocs so that
we can parse their contents as templates that may span multiple tokens.
2017-05-28 09:36:32 -07:00
Martin Atkins
5898b36695 zclsyntax: scan single-character tokens that represent themselves
For convenience we use the rune values of these tokens as their token
enum values, so we can handle them all via a single rule.
2017-05-28 09:34:20 -07:00
Martin Atkins
53944335f1 zclsyntax: identifiers in the scanner 2017-05-28 09:16:53 -07:00