Commit Graph

56 Commits

Author SHA1 Message Date
Torin Sandall 557f8bb999 ast: Update parser to support rule assignments
Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-08-07 14:22:45 -04:00
Torin Sandall 7543970087 Fix parser to avoid duplicate comments in AST
The parser was accumulating comments in a parser-global slice. If the
parser backtracked, the comments were not thrown away. Because most
successful parses seem to backtrack, this meant that most ASTs contained
duplicated comments.

This change simply modifies the parser to accumulate the comments in a
set that just gets sorted at the end.

Fixes #426

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-01-08 17:21:50 -08:00
Stephan Renatus 59f7020d2d parserErrorDetail: fix '^' location of lines starting with tabs
Fixes #1129 for the most part.

What still is wrongly put, but also harder to fix, is the case where
there's tabs INSIDE the line:

	p = TAB true TAB { TAB as }

or a space before the tab, like

	SPACE TAB p = true { as }

will still have a misaligned "^", as in that case, not all tabs are
fully expanded.

This merely trims leading tabs, and fixes the error maker location if
there's no other tabs used in the line.

However, that should fit common usage: Leading tabs is what `opa fmt`
proposes; and I'm doubtful of too many uses of tabs in other places
in Rego code.

Signed-off-by: Stephan Renatus <srenatus@chef.io>
2019-01-08 08:00:11 -08:00
Torin Sandall 64722e7110 Fix panic in parser error detail construction
The parser was panic-ing when constructing an error detail because it
could index into the line with a negative offset. These changes improve
the improve the checks against the position input.

Fixes #948

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2018-09-18 11:13:59 -07:00
Torin Sandall 6f7d273914 Remove dead code around parser error handling
Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2018-07-26 16:37:03 -07:00
Torin Sandall 8950d43796 Improve parser error readability
PreviousLy if a match failure occurred, the error would be returned to
the caller as is. Because of how the grammar is specified this often
resulted in noisy error messages that list all of the low level symbols
that the parser _tried_ to match (e.g., #, %, /, >, etc.) The expected
values are basically useless for users.

With these changes the expected values are removed from the parser
errors and the parser errors now include the text from the line in
question and a carrot identifying where the failure occurred.

These changes also improve the error hanlding for non-terminated strings
and other well-known classes of parser errors. In the future we can
improve the parser to return more specific errors that are more useful
than the "no match found" default.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2018-07-26 16:37:03 -07:00
Torin Sandall 31950fda8b Fix location on rules parsed from call exprs 2018-03-09 11:17:36 -08:00
Torin Sandall 658ae9fe75 Refactor AST type name strings
Previously we had constants defined for AST type names. These were used
in error messages in various places. The original goal was to make error
messages consistent, however, this approach made it difficult to locate
the source of the error in code.
2018-02-09 16:38:34 -08:00
Torin Sandall 02e68689da Add support for calls as values
These changes allow calls to be nested inside terms (e.g., f(x) !=
g(x)). As part of these changes a few things have been refactored:

1) Grammar has been restructured so that construction code is pulled out
into a separate file. Hopefully this makes the grammar more readable.

2) String() implementation on Expr has been simplified to use prefix
notation for calls (except equality) as this avoids the challenge of
worrying about roundtripping policy strings (which is done frequently
inside test cases.) E.g., plus(x,1,y) converted to infix x + 1 = y would
parse to eq(x + 1, y).
2018-01-26 18:05:05 -08:00
Torin Sandall 10182050d6 Refactor wildcard mangling
Use the ast.Transform utility instead of ast.Visit so that nodes are not
mutated in-place as this corrupts the set and hash data structures.
2017-12-15 09:16:34 -08:00
Torin Sandall 3091c26a81 Fix wildcard mangling in rule head
Now that the AST walker can visit terms (as well as values) it's better
to just walk all terms in the statement and mangle them (rather than
relying on speical handling for collections of terms, which is bound to
break over time.)

Fixes #480
2017-10-13 15:02:41 -07:00
Torin Sandall 7ca542adb5 Refactor functions implementation
Previously, functions were implemented with a separate set of types that
had their own code paths in the compiler, eval, etc. These changes
refactor the function implementation so that functions are implemented
as rules with one or more arguments.

By representing functions as rules, we can avoid special casing required
to support functions, e.g., during parse and compile there are a number
of steps that required special casing for functions:

- Parser needed separate grammar definitions for functions (which
  prevented them from being chained or using else)

- Compiler needed separate resolver and type checker implementations
  which was a source of bugs.

In some cases, special casing is unavoidable for now (e.g., during eval)
however this could be improved in the future.

Fixes #471
Fixes #467
Fixes #463
2017-10-10 08:57:58 -07:00
Torin Sandall 2401f782f3 Fix incorrect REPL interpretation of some exprs
These changes refactor the parser extensions that convert bodies into
rules if they can interpreted as such. The cases that can be converted
are clearer now and the test coverage is improved.

Fixes #433
2017-08-29 15:44:17 -07:00
Torin Sandall 588cc82f11 Add support for partial doc shorthand
These changes allow partial docs to be defined without a body in Rego
source files. Before, the rules would have to include a `{true}` body
for the parser to allow them. Now, the body can be omitted.

Rules defined this way (inside modules) cannot be copy/pasted as-is into
the REPL. This could be addressed by creating a "paste mode" in the REPL
similar to ipython and other interactive shells.

These changes build on https://github.com/open-policy-agent/opa/pull/412
with a few differences:

- Dynamic values are allowed in the head.
- Partial sets are allowed.

Both of these changes are based on personal experience writing policy.
Dynamic values are fine to allow as the compiler will catch unsafe vars
and rewrite the head to handle refs and comprehensions.
2017-08-24 11:29:14 -07:00
Matthew Mussomele f16d0b9960 Correct data race in the parser extensions
When the parser is post-processing parsed Rego, it takes steps to
transform variable references to the `data` and `input` root documents
into Refs with the variables as the head. It does this using the
Transform function of the ast package, which will proceed to transform
the new Ref as well. While it would always replace the ref head with
itself, the Go race detector correctly saw concurrent reads and writes
to the Ref as a data race. The parser extensions have been corrected to
replace variable instances of the root documents with separate copies of
their Ref counterparts, instead of using a single global instance of
each across calls.
2017-08-07 14:13:11 -07:00
Matthew Mussomele 389d681388 Update ast to support user functions 2017-07-05 13:45:55 -07:00
Matthew Mussomele 45af66c63b Correct OPA fmt to leave policy constants as Bodies
When parsing, OPA transforms constants into rules with only the
expression `true` in the body. This is not desirable behavior, as
it's much cleaner for them to be expressed in the shorthand.

This patch also adds a test for parsing invalid rego.
2017-06-30 10:51:10 -04:00
Matthew Mussomele 3ed5fd2430 Properly set location on converted constants
OPA converts lone bodies to rules containing a single expression
in their bodies (true). However, the parser extension that did this
neglected to set the location of the new rule and the new expression.
2017-06-30 10:51:10 -04:00
Matthew Mussomele f8ae1b8147 Set the filename for AST Locations in the parser
This eliminates the need to set the filename during parser
post-processing.
2017-06-29 13:10:36 -04:00
Matthew Mussomele c447252b95 Add Locations to Rules in the AST
This is needed for proper formatting of closing braces.
2017-06-29 13:10:36 -04:00
Matthew Mussomele 743a7b0812 Add Comments to the AST
Comments weren't useful before, but will be needed when formatting
rego code in a future patch.
2017-06-29 13:10:36 -04:00
Torin Sandall 44e39fda32 Fix setting of term locations
There were a handful of places in the parser where the location was not
being set on terms. All parsed terms should have a location set (for
debug/error purposes.) These changes correct the missing cases in the
parser. Also, now that the visitor can process terms, we can add back
the filename setter on terms.
2017-06-17 10:27:47 -07:00
Torin Sandall 0c8b37db45 Update walker to call AST visit function on Term
Before, the walker would skip the Term and move straight to the Term
value. In some cases, it's useful to be able to process Terms
generically.

Note, this required removing the filename setter as some terms do not
have a location set. This is a separate issue that will be fixed in the
next commit.
2017-06-17 10:27:47 -07:00
Torin Sandall 14e35b0d29 Add else keyword support to ast package
These changes update the parser, compiler, and related helpers to
support the else keyword.

These changes do not include the updates required for rule indexing.
2017-05-26 11:55:49 -07:00
Torin Sandall baefc77ef7 Fix bug in ast.ParseTerm
ParseTerm should have been checking if body was exactly size 1. This was
allowing the form in index.html to trigger a panic if the input field
was empty.
2017-05-17 07:22:36 -07:00
Torin Sandall 3a2314f5f5 Add module pointer to rules
Given a parsed rule, it should be easy to determine the path of the
document produced by that rule without having access to the entire that
the rule is contained in.
2017-04-26 15:04:48 -07:00
Torin Sandall 039c7bdd02 Update error codes and messages throughout
- Refactor error codes to use strings instead of ints.

- Simplify error messages throughout.

- Ensure location set on all expressions. There were a couple locations
  in the parser/compiler where locations were not being set.

- Fallback to rule location in topdown in case location not set. This
  ensures that users get useful locations for API requests with paths
  that refer to virtual docs exactly.

Also add Find function to ast.Value. Useful for extracting values
dynamically. Eventually can support JSON pointers.

Fixes #237
2017-02-16 10:29:57 -08:00
Torin Sandall 63b7e7e1fe Fix parsing of inline comments
Fixes #258
2017-02-13 14:28:33 -08:00
Torin Sandall 49a963f16a Fix test cases to work with new syntax 2017-02-10 10:37:43 -08:00
Torin Sandall b1349c8a17 Update Rego syntax
This commit contains a few syntax/parsing changes:

1) Old head :- body rule syntax is no longer supported. All rules must
be declared as: head { body } now.

2) Semicolon has replaced comma as the conjunction operator. This avoids
the ambiguity between set literals and curly-brace enclosed bodies.

3) ast.ParseBody will concatenate bodies that it receives from the
parser. This way, callers can invoke ast.ParseBody without enclosing
multiple expressions in braces.

4) Trailing commas are allowed in sets, arrays, and objects. To declare
a set of size one a trailing comma must be used, e.g., {foo,} =>
set(foo) where as {foo} => body(expr(foo)).

The following commit will update all of the existing test cases to bring
them into compliance with the new syntax.

Fixes #253
2017-02-10 10:37:43 -08:00
Torin Sandall f8a5728f47 Add support for enclosed bodies
As part of this change, the scheduler policy has been updated to test
the new syntax end-to-end.

Fixes #242
2017-02-07 11:34:25 -08:00
Torin Sandall 04c603a059 Refactor to use ast.Head throughout OPA
Instead of storing all head attributes on the rule directly, use the
ast.Head structure that was introduced a little while ago.
2017-02-03 09:02:22 -08:00
Torin Sandall 5906ea302b Update ast to support with modifier 2017-02-03 08:39:35 -08:00
Torin Sandall ebc753cfd8 Rename the request document
Naming is hard. The "request" document is now the "input" document.
2017-01-18 16:37:32 -08:00
Torin Sandall 699e45db20 Improve module parsing errors
Fixes #213
2017-01-18 12:22:37 -08:00
Torin Sandall 9c87bbf0ef Refactor parser helpers to return Statement
As part of this change, comments have been added into the AST however they are
not stored on other AST nodes or the module for now (so this should not affect
any part of compilation or evaluation).
2017-01-18 12:22:37 -08:00
Torin Sandall 7f0930be92 Fix body to rule conversion bug
With the request document changes, the "request" var in "request = <term>"
is transformed into a ref. As a result, the body to rule conversion was not
working (and returning an error).

Fixes #202
2016-12-21 09:16:20 -08:00
Torin Sandall c1fe93b221 Update ast package with request changes 2016-12-19 09:51:27 -08:00
Torin Sandall f64d75aee2 Update parser support for <var> = <term> rules
Fixes #192
2016-12-13 18:44:16 -08:00
Torin Sandall 26faa743cb Fix parser handling of keywords in variable names
The grammar was incorrectly attempting to match keywords to prevent them from
being used as variable names. Now, the parser includes a predicate function to
check that keywords are not used in place of variable names.

Fixes #178
2016-11-29 16:08:48 -08:00
Torin Sandall f876a70a5a Add parser utilities for packages and imports 2016-11-24 11:03:43 -08:00
Torin Sandall 710b0ba03a Fix parser to transform data var into ref
Previously, the token "data" would be parsed into Var("data"). Because "data"
is a reserved word, it would pass the safety checks and then fail to evaluate.

With this change, Var("data") is transformed into Ref("data"). This means the
safety checks will catch the recursion (instead of failing during evaluation).
2016-11-24 08:54:47 -08:00
Torin Sandall e44f44cb1d Update parser and compiler to support sets 2016-11-01 11:14:28 -07:00
Torin Sandall 1a6d7a5a09 Include location attribute on ast errors
Previously, errors returned by the parser and compiler would encode the
location information in the error string. Now, the location information is
structured and can be readily used by consumers.
2016-10-25 09:26:36 -07:00
Torin Sandall 048afcdcf8 Fix error messages if no parser match found
As mentioned in the comment, this is a workaround for an issue in the parser.
If the parser does not find a match for any of the rules, it returns a bogus
error location.
2016-10-24 11:48:22 -07:00
Torin Sandall a7a83d7221 Add helper to parse single expression 2016-10-21 16:58:46 -07:00
Torin Sandall 5a4f4c06a6 Add Index field to ast.Expr
This will allow callers to unambiguously compare expressions contained in an
ast.Body. E.g., the query "p[x], p[x]" contains two separate but syntactically
equal expressions. The new field will allow callers to distinguish between
them.

Also, refactor code that manually constructs ast.Body. Instead, call NewBody
which will handle setting the new field correctly.
2016-10-11 10:49:32 -07:00
Torin Sandall 30aa306d49 Error message improvements
These changes add some helpers to obtain contextual information for error
mesasages. Specifically, the Location values on all AST nodes can be used to
format error messages that include line, column, and filename.

Also, add compiler step to check that built-ins are provided with the correct
number of arguments. The built-in implementations in topdown assume this is
the case and will index into the term slice without checking.
2016-07-05 11:39:25 -07:00
Torin Sandall 99928b536a Set filename on Location objects 2016-06-30 16:33:44 -07:00
Torin Sandall edab7bcc7f Update parser extension to take filename 2016-06-30 16:33:44 -07:00