Skip to content

Parse left- and right-assoc #2252

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

Merged
merged 28 commits into from
Nov 13, 2020

Conversation

ttuegel
Copy link
Contributor

@ttuegel ttuegel commented Nov 6, 2020

Fixes #2124


Reviewer checklist
  • Test coverage: stack test --coverage
  • Public API documentation: stack haddock

@ttuegel ttuegel force-pushed the feature--assoc-parser branch from a3c1247 to 7e0553f Compare November 10, 2020 18:40
@ttuegel ttuegel force-pushed the feature--assoc-parser branch from 7e0553f to 06bf285 Compare November 10, 2020 18:50
@ttuegel ttuegel marked this pull request as ready for review November 10, 2020 18:59
Copy link
Contributor

@ana-pantilie ana-pantilie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parser looks much cleaner to me now. I'm also wondering why the sentence type used to take a type variable in the first place. I have some questions but they're mostly for my own understanding, and I also have a couple of minor suggestions.

sortIdParser :: Parser Id
sortIdParser = idParser
parseSortId :: Parser Id
parseSortId = parseId <?> "sort identifier"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm not very familiar with <?>. From the documentation, I see it says that <?> replaces the parsed token with "sort identifier" if it fails to parse any input. Does this mean that "sort identifier" will be part of the error message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the error message will be:

unexpected ...
expected sort identifier

type Parser = Parsec String String
type Parser = Parsec ReplParseError String

newtype ReplParseError = ReplParseError { unReplParseError :: String }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the benefits of using a newtype with an IsString instance here rather than String directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we use String directly, we have to declare an orphan instance.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's right, we needed the ShowErrorComponent instance.

(Pattern variable Attribute.Null)
where
from = Recursive.embed . (:<) Attribute.Null . from
{-# INLINE CONLIKE from #-}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I fully understand what CONLIKE does from the GHC documentation, I'll keep in mind to try to learn more about it, but could you give me some hints related to why it was necessary here? Did something not work properly or is there something specific about this code which makes a pragma like this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CONLIKE is short for "constructor-like". This tells GHC that this function is inexpensive to compute, like a constructor. This will make the compiler very aggressive about inlining it. I'm using it here because I know that all these functions put together are just applying several constructors on top of the argument.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand now, thank you!

@ttuegel
Copy link
Contributor Author

ttuegel commented Nov 12, 2020

I'm also wondering why the sentence type used to take a type variable in the first place.

It was due to the class AsSentence, which I removed. We needed all the branches of the Sentence sum type to have the same parameters because there was once a functional dependency on this class. Without the functional dependency, we would need a type annotation in every place that asSentence was used. I was able to replace it with From, and I only had to add two or three type applications to make everything typecheck.

Comment on lines -68 to -78
takeWhile :: (Char -> Bool) -> Parser String
takeWhile = takeWhileP Nothing

{-|'endOfInput' is similar to Attoparsec's 'endOfInput'. It matches only the
end-of-input position.
-}
endOfInput :: Parser ()
endOfInput = eof

instance ShowErrorComponent String where
showErrorComponent str = str
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we removing these utilities? (along with the rest from this file)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are all either re-exporting a library function under a non-standard name, or they are redefining a library function.

@ttuegel ttuegel merged commit 7579c77 into runtimeverification:master Nov 13, 2020
@ttuegel ttuegel deleted the feature--assoc-parser branch November 13, 2020 11:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update syntax and parser for left- and right-assoc notations
3 participants