-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merge ast and parser from forward #3
Conversation
This does not adapt the tests to the new features, it just makes sure there are no errors due to the renaming of classes or changed parameters in functions
None was never an allowed value for nodes in a networkx.DiGraph, but older versions of networkx apparently didn't throw an error when it was added
…at I just spent hours figuring out
This reverts commit 077a5eb.
…ressions" This reverts commit 2afe578.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot, excellent work! I just added some comments. Please make sure each file has an empty line at the end (otherwise Github shows the ugly red icon at the end). There might also be a bug in the change to cfg.py
. The linter found a bunch of minor problems, it would be great if you could fix them as well. See https://github.com/Philipp15b/probably/runs/6505098898?check_suite_focus=true.
We should also note all breaking changes in this pull request so we can update other tools that depend on it. I see the following:
- Changed names
FloatLitExpr
toRealLitExpr
- Changed operator precedence so that the
:
operator now binds less strong than multiplication (what does that mean in practice, do we have an example?) - Changed the constructor of the
Program
class and theProgram.from_parse
function to require one more parameter - Probably now depends on at least Python 3.9
- Rename
Assoc.Left
toLEFT
andRight
toRIGHT
- More?
probably/pgcl/parser.py
Outdated
return PlotInstr(VarExpr(_parse_var(_child_tree(t, 0))), | ||
prob=lit) | ||
elif t.children[1].data == 'true' or t.children[1].data == 'false': | ||
raise SyntaxError("Plot instruction does not support boolean operators") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, belongs in the type checker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this actually resolved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is actually a bug in the parsing of plot instructions. If we write !Plot[x, true]
in pGCL, the true
is interpreted as a VarExpr
with value true
instead of as an (illegal) boolean literal.
Which also raises the question, shouldn't it be forbidden to have variables etc. that are called "true" or "false"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right! I guess the nicest way to solve this would be to parse full expressions in !Plot
and then have a check somewhere that it's actually a variable. That way, we can give proper error messages.
I had hoped that the parser would reject any keywords as variables, e.g. true := whatever
should give an error. If that's not the case, another bug! I'd solve that by manually rejecting all keywords such as true
and false
in the _parse_var
function:
probably/probably/pgcl/parser.py
Lines 183 to 186 in 6158b37
def _parse_var(t: Tree) -> Var: | |
assert t.data == 'var' | |
assert t.children[0].type == 'CNAME' # type: ignore | |
return str(_child_str(t, 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had hoped that the parser would reject any keywords as variables, e.g. true := whatever should give an error. If that's not the case, another bug!
Fixed by 0a598c2, at least for true
and false
(are there even more?).
I guess the nicest way to solve this would be to parse full expressions in !Plot and then have a check somewhere that it's actually a variable.
I feel like this is just treating the symptoms (i.e., retrospectively fixing that the tree generated by lark contains a var node where a literal should be) instead of fighting the actual cause (i.e., making sure that there isn't even a var node in the first place). Wouldn't it be more elegant to somehow change the lark grammar such that true
and false
are never recognized as variable names? If we do it like you propose, this check needs to occur after the parsing is finished, or we need a global list in the parser that contains all variables in the current program (similar to the parameter dict). Both of these possibilities seem wrong to me.
For example, commit 12167a5 does this. This fixes both of these problems, it just leads to some very cryptic error messages when a variable has an illegal name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do it like you propose, this check needs to occur after the parsing is finished, or we need a global list in the parser that contains all variables in the current program (similar to the parameter dict)
I don't understand that. Just check whether a variable name is a keyword and throw an error if that's the case. I think that's the easiest way to do this. As an additional safety measure, the constructor of VarExpr
could assert
that the name is not a keyword.
it just leads to some very cryptic error messages when a variable has an illegal name
This is exactly why we should be liberal in what we parse and then provide useful error messages afterwards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, more or less. It's still not in the typechecker, but wrongly typed code can't be parsed anyways in this case.
This comment was marked as duplicate.
This comment was marked as duplicate.
probably/pgcl/parser.py
Outdated
@@ -441,7 +441,8 @@ def _parse_query(t: Tree): | |||
assert isinstance(lit, RealLitExpr) | |||
return PlotInstr(VarExpr(_parse_var(_child_tree(t, 0))), | |||
prob=lit) | |||
elif t.children[1].data in ('true', 'false'): | |||
elif t.children[1].data in ('true', 'false') or \ | |||
(t.children[1].data == 'var' and t.children[1].children[0] in ('true', 'false')): | |||
raise SyntaxError("Plot instruction does not support boolean operators") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a workaround for the problem mentioned here, so we get a nicer error message. This check should still be moved to the typechecker, but I don't see how this can be done without some extensive rewrites, as the parsing of a PlotInstr
already depends on the type of the literal. Also, the parser throws an error that there is an illegal variable name anyways, this change here just changes the error message.
|
||
format: | ||
poetry run yapf -r -i probably/ tests/ | ||
poetry run isort probably/ tests/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isort
is not a dev-dependency, does this actually work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It runs on my machine... Maybe some other package depends on isort
? In any case, if this should stay here then we should probably add it to the dependencies
No description provided.