Use antlr v4 for syntax check - antlr

Can I use antlr v4 for syntax check before I actually run the code?
Example :
I defined syntax: select * from table, I want to know the statement is correct or not before actually executing it.
Following is my code :
val listener = new SQLListener()
val loadLexer = new SQLLexer(new ANTLRInputStream(input))
val tokens = new CommonTokenStream(loadLexer)
val parser = new SQLParser(tokens)
val stat = parser.statement()
I tried but DefaultErrorStrategy won't throw an Exception
I tried this:
parser.addErrorListener(new BaseErrorListener {
override def syntaxError(recognizer: Recognizer[_, _ <: ATNSimulator],
offendingSymbol: scala.Any,
line: Int,
charPositionInLine: Int,
msg: String, e: RecognitionException ): Unit = {
println("==========2============"+msg)
throw new AssertionError("line: " + line + ", offset: " + charPositionInLine +
", symbol:" + offendingSymbol + " " + msg)
}
})
but get this:
Error: Note: the super classes of contain the following, non final members named syntaxError:

If the input contains any syntax errors, this will call the visitErrorNode method on the listener. So if you define that method in your listener, you'll see any errors that occur.
If your listener is directly executing the code (rather than first building an AST or other form of IR), you probably won't want your listener to even start executing when there's a syntax error. One way to achieve that would be to set the BailErrorStrategy instead of the DefaultErrorStrategy as the error handling strategy of your parser (using setErrorHandler on the parser). This will throw an exception as soon as a syntax error occurs.
If you don't want to abort on the first error and/or you want some additional checks beyond just syntax errors (like checking for certain types of semantic errors), an alternative is to have a listener just to perform those checks. Then you'd run your code-executing listener only if the error-checking listener does not find any errors.

You are on the right track here. Use your error listener to store the errors in a list while parsing. Afterwards you can then check that list.
That requires however not to do any action during the parsing process (e.g. in a parse listener) other than stuff related to the parsing process itself. Any follow up action (e.g. error markup in an editor) should be done after the parse run.
If you like to see an example of an application using this approach take a look at the parser module implementation of MySQL Workbench. It also demonstrates the 2-stage parsing strategy for quicker parsing.

Related

How do you serialize a fragment of an Xtext parse tree/AST?

I have some xtend code that gets a parse tree/AST from a file in my DSL.
I want a method that will serialize any node in the tree. This means I want text in the language of my DSL for an EObject somewhere in the parse tree.
So, if a program in my language is
class C {
int foo = 3;
}
the parse tree might look like
MyProgram
|_ MyClass
|_MyFieldDecl
|_Type
| |_IntType
|_Identifier
|_Expression
|_LiteralInteger
If I assigned a variable x the MyFieldDecl object in the tree, then I might want to call
var s = serialize(x)
to get the String, "int foo = 3;"
So, how do I implement that serialize() function?
The code I find when searching around will serialize the entire tree but not a node/fragment.
I found things in the xtext core code that appear to be doing this with either some instance of ISerializer or GrammarAccessExtensions. I tried to inject
#Inject #Extension GrammarAccessExtensions _grammarAccessExtensions
and get the serialization using
val s = _grammarAccessExtensions.grammarFragmentToString(e, prefix);
where e is an EObject, some node in the parse tree.
That failed on the statement
val main = injector.getInstance(MyClass)
with this error:
Exception in thread "main" com.google.inject.ConfigurationException: Guice configuration errors:
1) No implementation for org.eclipse.xtext.xtext.generator.model.project.IXtextProjectConfig was bound.
while locating org.eclipse.xtext.xtext.generator.model.project.IXtextProjectConfig
for field at org.eclipse.xtext.xtext.generator.XtextGeneratorNaming.projectConfig(Unknown Source)
while locating org.eclipse.xtext.xtext.generator.XtextGeneratorNaming
for field at org.eclipse.xtext.xtext.generator.grammarAccess.GrammarAccessExtensions._xtextGeneratorNaming(Unknown Source)
while locating org.eclipse.xtext.xtext.generator.grammarAccess.GrammarAccessExtensions
for field at myorg.MyClass._grammarAccessExtensions(Unknown Source)
while locating myorg.MyClass
1 error
at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1004)
at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:961)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1013)
at myorg.MyClass.main(MyClass.java:435)
I think this means I need to bind or inject things, but I just started working with this code base a couple of days ago, and all of this is new to me.
I also tried to copy code out of the xtext core to get an ISerializer and call
s = GrammarAccessExtensions.grammarFragmentToString(serializer, e, prefix)
That failed with this:
java.lang.NullPointerException: Invalid context: Grammar returns ScenarioModel

Is it possible to retrieve the namespace of a raised error?

When I raise an error from within an XQuery query, for instance with:
error( fn:QName( 'http://example.com', 'XMPL0001' ), 'Conflict' )
... the following is returned by BaseX (be it when communicating with the server, or from within the GUI)
Stopped at ., 1/7:
[XMPL0001] Conflict
Is it somehow possible to retrieve the namespace of the error (in this case http://example.com) as well?
I'm using a customized PHP client and I would like to use this information to prevent possible (future) conflicts with my custom error codes and parse the errors to throw either a standard BaseX\Exception or a custom SomeNamespace\Exception, depending on the namespace of the error.
I could, of course, simply use another error code pattern than the typical ABCD1234 XQuery pattern, to prevent possible (future) error code conflicts, but the possible use of a namespace appeals to me more, because I can then define an uniform Exception interface, such as:
interface ExceptionInterface
{
public function getCategory(); // the 4 alpha character part
public function getCode(); // the 4 digit part
}
I'm currently using BaseX 7.7.2, by the way.
Yes, you can retrieve information about the error using a few variables in the error namespace, which are in scope of the try-catch statement, like so:
declare namespace err = "http://www.w3.org/2005/xqt-errors";
try {
error( fn:QName( 'http://example.com', 'XMPL0001' ), 'Conflict' )
}
catch * {
namespace-uri-from-QName($err:code)
}
This assumes that you are using XQuery 3.0.

Debugging u-sql Jobs

I would like to know if there are any tips and tricks to find error in data lake analytics jobs. The error message seems most of the time to be not very detailed.
When trying to extract from CSV file I often get error like this
Vertex failure triggered quick job abort. Vertex failed: SV1_Extract[0] with >error: Vertex user code error.
Vertex failed with a fail-fast error
It seems that these error occur when trying to convert the columns to specified types.
The technique I found is to extract all columns to string and then do a SELECT that will try to convert the columns to the expected type. Doing that columns by columns can help find the specific column in error.
#data =
EXTRACT ClientID string,
SendID string,
FromName string,
FROM "wasb://..."
USING Extractors.Csv();
//convert some columns to INT, condition to skip header
#clean =
SELECT Int32.Parse(ClientID) AS ClientID,
Int32.Parse(SendID) AS SendID,
FromName,
FROM #data
WHERE !ClientID.StartsWith("ClientID");
Is it also possible to use something like a TryParse to return null or default values in case of a parsing error, instead of the whole job failing?
Thanks
Here is a solution without having to use code behind (although Codebehind will make your code a bit more readable):
SELECT ((Func<string, Int32?>)(v => { Int32 res; return Int32.TryParse(v, out res)? (Int32?) res : (Int32?) null; }))(ClientID) AS ClientID
Also, the problem you see regarding error message being cryptic has to do with a bug that should be fixed soon in returning so called inner error messages. The work around today is to do the following:
In the ADL Tools for VisualStudio, open the Job View of the failed job.
In the lower left corner, click on “resources” link in the job detail area.
Once the job resources are loaded, click on “Profile”.
Search for the string “jobError” at the beginning of the line. Copy the entire line of text and paste in notepad (or other text editor) to read the actual error.
That should give you the exact error message.
Yes, you can use TryParse using U-SQL user defined functions. You can do this like:
In code behind:
namespace TestNS
{
public class TestClass
{
public static int TryConvertToInt(string s)
{
int i = 0;
if (Int32.TryParse(s, out i))
return i;
return 0;
}
}
}
In U-SQL Script:
TestNS.TestClass.TryConvertToInt(ClientID) AS clientID
It looks like you have some other issues, as I always get appropriate error in case of conversion problem, something like:
"E_RUNTIME_USER_EXTRACT_COLUMN_CONVERSION_INVALID_ERROR","message":"Invalid character when attempting to convert column data."

Xtext: Customizing Error msg by unordered groups

I've defined an unordered group and it works like I expected. The only thing I would like to change is the error msg, which appears when an element of an unordered group isn't modelled yet. Is there an easy way to solve this? I tried already custom checks, but there I got an unexpected behaviour.
Following my rule for the unordered group and the error msg:
Element:
(name=ConfigurationName) &
(description=Description)? &
(tool=Tool) &
(model=Model) &
(interfaces=Interfaces)? &
(paramaters=Parameters)? &
(paramfile=ParamFile)?
;
rule ruleElement failed predicate: {getUnorderedGroupHelper().canLeave(grammarAccess.getElementAccess().getUnorderedGroup())}?
I want to change this error msg to something like: "The following elements are required in the configuration:...."
Xtext has a service called SyntaxErrorMessageProvider that is used to reword parser error messages. You have to define your messages on the parser level (so there will be no EMF model to use), but it is possible to get the original error message and the context, traverse it and provide your own error message.
To register this, open the «YourLanguage»RuntimeModule class, and add the following method:
public Class<? extends ISyntaxErrorMessageProvider> bindISyntaxErrorMessageProvider() {
return «YourLanguage»SyntaxErrorMessageProvider.class;
}
where «YourLanguage«SyntaxErrorMessageProvider is a class introduced by you, extending the class SyntaxErrorMessageProvider, where you can implement your custom function.
I works Automatic Validation customize,I create
public class MyDslLanguageSyntaxErrorMessageProvider extends SyntaxErrorMessageProvider {
}
And I Register it in the MyDslRuntimeModule:
public Class bindISyntaxErrorMessageProvider() {
return MyDslLanguageSyntaxErrorMessageProvider.class;}
But my problem is which package is used for this customization.I used org.xtext.example.mydsl.validation package for create java class .Also I do this customization with xtend class.I do not find enough source in the internet :(
You can use Java to write this Custom SyntaxErrorMessageProvider class, but to bind this you can bind in Runtime Module class. Also u can use any package to declare this class but declaring this class in same package where u have Runtime class makes sense

PHP error_log errors to MySQL

In a previous ticket i asked about logging PHP errors in MySQL which gives me:
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
// mysql connect etc here...
$sql = "INSERT INTO `error_log` SET
`number` = ".mysql_real_escape_string($errno).",
`string` = ".mysql_real_escape_string($errstr).",
`file` = ".mysql_real_escape_string($errfile).",
`line` = ".mysql_real_escape_string($errline);
mysql_query($sql);
// Don't execute PHP internal error handler
return true;
}
// set to the user defined error handler
$new_error_handler = set_error_handler("myErrorHandler");
I can make this work but only if it is triggerred like this:
trigger_error("message here");
However, I also want the error handler to be called for all errors such as syntax errors like:
echo "foo;
But these errors are just outputted to the screen, what am i doing wrong?
You can only handle runtime errors with a custom error handler. The echo "foo error in your example happens when parsing (i.e. reading in) the source. Since PHP can not fully parse the code, it can also not run your error handler on this error.
If You're forced to test if syntax is correct, You can use php_check_syntax function, with filename parameter PHP Manual php_check_syntax
php_check_syntax also provides second parameter, witch when used will be populated by the error string, as far as i remember
That's indeed terrible way of error logging
You don't need not a single advantage of a database. Would you make a database lookup for the certain line number? Or order your results by file name?
database is a subject of many errors itself.
You've been told already that it's impossible to catch a parse error at the program logic level, because a syntactically wrong program will never run.
Let's take your code as an example. It will raise a MySQL error (because of poorly formed query) which you will never see. As well as any other errors occurred. That's what I am talking about.