antlr4 error handling doesn't even compile - antlr4

I followed the instructions for error handling at the antlr website http://www.antlr2.org/doc/err.html (it says antlr2 but I couldn't find an alternative for antlr4) and wrote the exception handling for my rule as below.
subStmt :
(visibility WS)? (STATIC WS)? SUB WS? ambiguousIdentifier (WS? argList)? endOfStatement
block?
END_SUB
;
exception
catch [RecognitionException ex] {
}
But when I try to generate the Parser for the grammar it fails as below:
java -jar ../Downloads/antlr-4.7-complete.jar vba.g4 -package vba -o out
error(50): vba.g4:500:4: syntax error: 'catch' came as a complete surprise to me while matching rule preamble
Any help is much appreciated.

Antlr4 is quite different to Antlr2. Start by having a look at this question (and the answer):
How to implement error handling in ANTLR4
Update with a simple approach:
For error reporting, the basic approach is to make a class that implements the ANTLRErrorListener interface. BaseErrorListener has empty implementations for all the methods so you only need to implement the ones you care about. You probably care about syntaxError() the most.
On your parser object, call removeErrorListeners() to clear the internal error listener, and then call addErrorListener() with an instance of the class you want to handle your errors.
You will then get syntaxError() calls on that class when errors are encountered during a parse.
The other methods might (or might not) let you do what you want to do; I haven't used this interface to recover from parse errors.
For recovering from particular errors, you can implement a class with the ANTLRErrorStrategy interface. That gets complicated; see DefaultErrorStrategy for the default implementation.
A very simple approach is to deal with the possible errors in your grammar. Not sure how far you can go with this, but this is likely to be the easiest approach.

Related

Nice Error Messages for "no viable alternative at input '<EOF>'" in ANTLR4

I want to show more beautiful error message to my users.
For example if someone types integer i= the error message no viable alternative at input '<EOF>' appears. That's totally fine and predictable due to my grammar rules but I'm figuring out ways to improve those messages. If the = is missing in the example above the message changes to mismatched input '<EOF>' expecting '='. Again predictable but I can do more stuff on things like this in my code than on a general input error.
Should I catch them in the code and try to evaluate which cases is meant? Or is there a better way to handle this?
Typically you'd create your own error listener and add it to the parser where you can deal with the error yourself. For that remove any existing error listeners (one for the console is automatically registered by default), by calling parser.removeErrorListeners();. Define an own error listener class derived from BaseErrorListener and add an instance of that to your parser via parser.addErrorListener(yourListener);. You can see an example of such a custom error listener in the ANTLR runtime (search for XPathLexerErrorListener). Override the syntaxError method and use the provided info to generate your own error message. There is already a message passed in to this method (in addition to other stuff like line + char position, exception etc.), which you cannot customize as it comes directly from generated code. So best is probably to leave that alone and start from scratch (the passed in exception is your best option you have).

Common php functions in hack

I decided to start a new project to get into hacklang, and after fixing some if the problems I initially ran into transitioning from php habits, I ran into the following errors:
Unbound name: str_replace
Unbound name: empty
Doing some research I found that this is due to using 'legacy' php which isn't typechecked, and will error with //strict.
That's fine and all, empty() was easy enough to replace, however str_replace() is a bit more difficult.
Is there an equivalent function that will work with //strict? Or at least something similar.
I'm aware that I could use //decl but I feel like that defeats the purpose in my case.
Is there at least any way to tell which functions are implemented in hack and which are not in the documentation as I couldn't find one?
For reference (though it isn't too relevant to the question itself), here is the code:
<?hh //strict
class HackMarkdown {
public function parse(string $content) : string {
if($content===null){
throw new RuntimeException('Empty Content');
}
$prepared = $this->prepare($content);
}
private function prepare(string $contentpre) : Vector<string>{
$contentpre = str_replace(array("\r\n","\r"),"\n",$contentpre);
//probably need more in here
$prepared = Vector::fromArray(explode($contentpre,"\n"));
//and here
return $prepared;
}
}
You don't need to change your code at all. You just need to tell the Hack tools about all the inbuilt PHP functions.
The easiest way to do this is to download this folder and put it somewhere in your project. I put it in a hhi folder in the base of my project. The files in there tell Hack about all the inbuilt PHP functions.
Most of them don't have type hints, which can lead to Hack thinking the return type of everything is mixed instead of the actual return, that is actually correct in most cases as, for example, str_replace can return either a string or a bool. However, it does stop the "unbound name" errors, which is the main reason for adding them.

Ignore certain TypeScript compile errors?

I am wondering if there is a way to ignore certain TypeScript errors upon compilation?
I basically have the same issues most people with large projects have around using the this keyword, and I don't want to put all my classes methods into the constructor.
So I have got an example like so:
TypeScript Example
Which seems to create perfectly valid JS and allows me to get around the this keyword issue, however as you can see in the example the typescript compiler tells me that I cannot compile that code as the keyword this is not valid within that scope. However I don't see why it is an error as it produces okay code.
So is there a way to tell it to ignore certain errors? I am sure given time there will be a nice way to manage the this keyword, but currently I find it pretty dire.
== Edit ==
(Do not read unless you care about context of this question and partial rant)
Just to add some context to all this to show that I'm not just some nut-job (I am sure a lot of you will still think I am) and that I have some good reasons why I want to be able to allow these errors to go through.
Here are some previous questions I have made which highlight some major problems (imo) with TypeScript current this implementation.
Using lawnchair with Typescript
Issue with child scoping of this in Typescript
https://typescript.codeplex.com/discussions/429350 (And some comments I make down the bottom)
The underlying problem I have is that I need to guarantee that all logic is within a consistent scope, I need to be able to access things within knockout, jQuery etc and the local instance of a class. I used to do this with the var self = this; within the class declaration in JavaScript and worked great. As mentioned in some of these previous questions I cannot do that now, so the only way I can guarantee the scope is to use lambda methods, and the only way I can define one of these as a method within a class is within the constructor, and this part is HEAVILY down to personal preference, but I find it horrific that people seem to think that using that syntax is classed as a recommended pattern and not just a work around.
I know TypeScript is in alpha phase and a lot will change, and I HOPE so much that we get some nicer way to deal with this but currently I either make everything a huge mess just to get typescript working (and this is within Hundreds of files which I'm migrating over to TypeScript ) or I just make the call that I know better than the compiler in this case (VERY DANGEROUS I KNOW) so I can keep my code nice and hopefully when a better pattern comes out for handling this I can migrate it then.
Also just on a side note I know a lot of people are loving the fact that TypeScript is embracing and trying to stay as close to the new JavaScript features and known syntax as possible which is great, but typescript is NOT the next version of JavaScript so I don't see a problem with adding some syntactic sugar to the language as people who want to use the latest and greatest official JavaScript implementation can still do so.
The author's specific issue with this seems to be solved but the question is posed about ignoring errors, and for those who end up here looking how to ignore errors:
If properly fixing the error or using more decent workarounds like already suggested here are not an option, as of TypeScript 2.6 (released on Oct 31, 2017), now there is a way to ignore all errors from a specific line using // #ts-ignore comments before the target line.
The mendtioned documentation is succinct enough, but to recap:
// #ts-ignore
const s : string = false
disables error reporting for this line.
However, this should only be used as a last resort when fixing the error or using hacks like (x as any) is much more trouble than losing all type checking for a line.
As for specifying certain errors, the current (mid-2018) state is discussed here, in Design Meeting Notes (2/16/2018) and further comments, which is basically
"no conclusion yet"
and strong opposition to introducing this fine tuning.
I think your question as posed is an XY problem. What you're going for is how can I ensure that some of my class methods are guaranteed to have a correct this context?
For that problem, I would propose this solution:
class LambdaMethods {
constructor(private message: string) {
this.DoSomething = this.DoSomething.bind(this);
}
public DoSomething() {
alert(this.message);
}
}
This has several benefits.
First, you're being explicit about what's going on. Most programmers are probably not going to understand the subtle semantics about what the difference between the member and method syntax are in terms of codegen.
Second, it makes it very clear, from looking at the constructor, which methods are going to have a guaranteed this context. Critically, from a performance, perspective, you don't want to write all your methods this way, just the ones that absolutely need it.
Finally, it preserves the OOP semantics of the class. You'll actually be able to use super.DoSomething from a derived class implementation of DoSomething.
I'm sure you're aware of the standard form of defining a function without the arrow notation. There's another TypeScript expression that generates the exact same code but without the compile error:
class LambdaMethods {
private message: string;
public DoSomething: () => void;
constructor(message: string) {
this.message = message;
this.DoSomething = () => { alert(this.message); };
}
}
So why is this legal and the other one isn't? Well according to the spec: an arrow function expression preserves the this of its enclosing context. So it preserves the meaning of this from the scope it was declared. But declaring a function at the class level this doesn't actually have a meaning.
Here's an example that's wrong for the exact same reason that might be more clear:
class LambdaMethods {
private message: string;
constructor(message: string) {
this.message = message;
}
var a = this.message; // can't do this
}
The way that initializer works by being combined with the constructor is an implementation detail that can't be relied upon. It could change.
I am sure given time there will be a nice way to manage the this keyword, but currently I find it pretty dire.
One of the high-level goals (that I love) in TypeScript is to extend the JavaScript language and work with it, not fight it. How this operates is tricky but worth learning.

How does Langage.Haskell.TH.report work?

Unfortunately, many Template Haskell functions have absolutely no documentation at all. One such function is report. It takes a Bool and a String, and produces a compilation error with the specified string as the error message. Does anybody have any clue what the hell the Bool is for? As best as I can tell, either value does exactly the same thing...
If the Bool is True, an error is reported; if it is False, a "warning" is reported, meaning that the template code will continue to run to collect more "warnings."
Looking at the source code, report calls qReport, which is a method of some class called Quasi. This method actually has some damned documentation - though only a tiny snippet. I quote:
Report an error (True) or warning (False) ...but carry on; use fail to stop
So it seems to make my TH splice crash with an appropriate error message, I just need to call fail instead. Hopefully this information will be useful to anyone else trying to figure that out...

compiler warning on (ambiguous) method resolution with named parameters

One question regarding whether the following code should yield a compiler warning or not (it doesn't). It declares two methods of the same name/return type, one has an additional named/optional parameter with default value.
NOTE: technically the resolution isn't ambiguous, because the rules clearly state that the first method will get called. See here, Overload resolution, third bullet point. This behavior is also intuitive to me, no question.
public void Foo(int arg) { ... }
public void Foo(int arg, bool bar = true) { ...}
Foo(42); // shouldn't this give a compiler warning?
I think a compiler warning would be kind of intuitive here. Though the code technically is clean (whether it is a sound design is a different question:)).
I disagree that it needs a warning, actually. The main issue is, that code is potentially legitimate, and if that's the case you would have to explicitly disable the warning.
What I mean is, in general when you get a warning, you will be able to change your code to get rid of the warning (and presumably make the code better at the same time). But in this case, it may be that you did it like that intentionally and would not be able to change your code to get rid of the warning.
For example, the "unreachable code" warning is something you can just delete the unreachable code to get rid of the warning. Or the "could not find reference" warning - this is usually a signal that you're going to get "undefined type" errors, but if not then you can simply delete the reference. Or maybe "A previous catch clause already catches all exceptions" warning: in this case, you need to change your code so that either the new clause comes before the catch-all, or remove the catch altogether.
But the point is that in every case when you get a warning, you should change your code, and making the change will always result in "better" code. However, in the case of this question, the call is not ambiguous (as far as the compiler is concerned) and I don't think you can argue that it's always a mistake to write code like that, so therefore there shouldn't be a warning.
If the compiler issued a warning about every case where you do something that's probably not the best idea, then we'd be inundated with warnings!
Warnings are to notify programmers of potentially dumb mistakes. This is an area that could generate a dumb mistake, so yes, it should generate a warning. Are you trying to form a petition?

Resources