Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Testing the Grammar using the Parser and existing data set
Testing the Grammar using the Parser and existing data set [message #513285] Tue, 09 February 2010 11:20 Go to next message
Jabier  is currently offline Jabier
Messages: 10
Registered: July 2009
Junior Member
Dear all,

I am trying to implement a TestCase for the Parser of my DSL using JUnit. The language is called ML and we have hundreds of ML files I want to test in order to develop the grammar iteratively.

I create a plug-in fragment for the tests: company.ml.tests
with the following code for the TestCase.

package company.parser.antlr;

import java.io.FileInputStream;
import junit.framework.TestCase;
import org.antlr.runtime.ANTLRInputStream;
import org.eclipse.xtext.parser.IParseResult;

public class MLParserTest extends TestCase {

	public void testMLParser() {
		try {
			FileInputStream in = new FileInputStream(
					"E:/test.ml");
			ANTLRInputStream antlrIn = new ANTLRInputStream(in);
			MLParser parser = new MLParser();
			IParseResult parseResult = parser.parse(
					parser.getDefaultRuleName(), antlrIn);
			assertTrue("Parsing Error", parseResult.getParseErrors().isEmpty());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}


I execute it using Run us: "JUnit Plug-in Test" and I get this exception:

java.lang.NullPointerException
	at org.eclipse.xtext.parser.antlr.XtextTokenStream.<init>(XtextTokenStream.java:50)
	at company.parser.antlr.MLParser.parse(MLParser.java:27)
	at company.parser.antlr.MLParserTest.testMLParser(MLParserTest.java:16)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...



The problem seems to be that "antlrTokenDefProvider" is null when the test is executed. When creating new XtextTokenStream(lexer, antlrTokenDefProvider); in the following code the sentence tokenDefProvider.getTokenDefMap() is executed and this is why we have the exception.

public class MLParser extends org.eclipse.xtext.parser.antlr.AbstractAntlrParser {
@Inject 
    protected ITokenDefProvider antlrTokenDefProvider;
	
	@Inject
	private MLGrammarAccess grammarAccess;
	
	@Override
	protected IParseResult parse(String ruleName, ANTLRInputStream in) {
		company.parser.antlr.internal.InternalMLLexer lexer = new company.parser.antlr.internal.InternalMLLexer(in);
		XtextTokenStream stream = new XtextTokenStream(lexer, antlrTokenDefProvider);
		stream.setInitialHiddenTokens("RULE_WS", "RULE_ML_COMMENT", "RULE_SL_COMMENT");
...


I have shown a previous message #384429 about this topic but it didn't help me. I would like to use this approach.
Any idea? Maybe I am missing something about the @Inject or some dependency...

Thanks!
Jabi

[Updated on: Tue, 09 February 2010 11:54]

Report message to a moderator

Re: Testing the Parser using existing data set [message #513299 is a reply to message #513285] Tue, 09 February 2010 07:04 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian Zarnekow
Messages: 2788
Registered: July 2009
Senior Member
Hi Jabier,

Injector injector = new
MLStandaloneSetup().createInjectorAndDoEMFRegistration();
IParser parser = injector.get(IParser.class);

this should do the trick if you really want to work with the parser.
However, it is strongly recommended to use the EMF resource API to read
files:

ResourceSet set = injector.get(XtextResourceSet.class);
Resource res = set.getResource(URI.createURI("file.name"), true);
....

Regards,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com

Am 09.02.10 17:20, schrieb Jabier:
> Dear all,
>
> I am trying to implement a TestCase for the Parser of my DSL using
> JUnit. The language is called ML and we have hundreds of ML files I want
> to test in order to develop the grammar iteratively.
>
> I create a plug-in fragment for the tests: company.ml.tests
> with the following code for the TestCase.
>
>
> package company.parser.antlr;
>
> import java.io.FileInputStream;
> import junit.framework.TestCase;
> import org.antlr.runtime.ANTLRInputStream;
> import org.eclipse.xtext.parser.IParseResult;
>
> public class MLParserTest extends TestCase {
>
> public void testMLParser() {
> try {
> FileInputStream in = new FileInputStream(
> "E:/test.ml");
> ANTLRInputStream antlrIn = new ANTLRInputStream(in);
> MLParser parser = new MLParser();
> IParseResult parseResult = parser.parse(
> parser.getDefaultRuleName(), antlrIn);
> assertTrue("Parsing Error", parseResult.getParseErrors().isEmpty());
> } catch (Exception e) {
> e.printStackTrace();
> }
> }
>
> }
>
>
> I execute it using Run us: "JUnit Plug-in Test" and I get this exception:
>
>
> java.lang.NullPointerException
> at
> org.eclipse.xtext.parser.antlr.XtextTokenStream.<init>(XtextTokenStream.java:50)
>
> at company.parser.antlr.MLParser.parse(MLParser.java:27)
> at company.parser.antlr.MLParserTest.testMLParser(MLParserTest. java:16)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> ...
>
>
>
> The problem seems to be that "antlrTokenDefProvider" is null when the
> test is executed. When creating new XtextTokenStream(lexer,
> antlrTokenDefProvider); in the following code the sentence
> tokenDefProvider.getTokenDefMap() is executed and this is why we have
> the exception.
>
>
> public class MLParser extends
> org.eclipse.xtext.parser.antlr.AbstractAntlrParser {
> @Inject protected ITokenDefProvider antlrTokenDefProvider;
>
> @Inject
> private MLGrammarAccess grammarAccess;
>
> @Override
> protected IParseResult parse(String ruleName, ANTLRInputStream in) {
> company.parser.antlr.internal.InternalMLLexer lexer = new
> es.esi.fast.legacy.parser.antlr.internal.InternalMLLexer(in) ;
> XtextTokenStream stream = new XtextTokenStream(lexer,
> antlrTokenDefProvider);
> stream.setInitialHiddenTokens("RULE_WS", "RULE_ML_COMMENT",
> "RULE_SL_COMMENT");
> ...
>
>
> I have shown a previous message #384429 about this topic but it didn't
> help me. I would like to use this approach.
> Any idea? Maybe I am missing something about the @Inject or some
> dependency...
>
> Thanks!
> Jabi
>
Re: Testing the Parser using existing data set [message #513815 is a reply to message #513299] Thu, 11 February 2010 06:52 Go to previous messageGo to next message
Jabier  is currently offline Jabier
Messages: 10
Registered: July 2009
Junior Member
This code worked fine:
MLParser parser = injector.getInstance(MLParser.class);

Thanks! I am able to run the testing.
Now I am having problems getting the line of the SyntaxError for the message. I get the Node from the SyntaxError but it seems that line, totalLine, endLine etc. don't have an assigned value so I always get 0.
Any idea about that?
Re: Testing the Parser using existing data set [message #513869 is a reply to message #513815] Thu, 11 February 2010 09:39 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian Zarnekow
Messages: 2788
Registered: July 2009
Senior Member
Hi Jabier,

it is strongly recommended to use the EMF resource API instead of the
plain parser:

ResourceSet set = injector.get(XtextResourceSet.class);
// the following line will postprocess the parse result, perform
// linking etc
Resource res = set.getResource(URI.createURI("file.name"), true);
IParseResult result = ((XtextResource)res).getParseResult();

Regards,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com


Am 11.02.10 12:52, schrieb Jabier:
> This code worked fine:
>
> MLParser parser = injector.getInstance(MLParser.class);
>
> Thanks! I am able to run the testing.
> Now I am having problems getting the line of the SyntaxError for the
> message. I get the Node from the SyntaxError but it seems that line,
> totalLine, endLine etc. don't have an assigned value so I always get 0.
> Any idea about that?
icon14.gif  Re: Testing the Parser using existing data set [message #513920 is a reply to message #513869] Thu, 11 February 2010 11:39 Go to previous messageGo to next message
Jabier  is currently offline Jabier
Messages: 10
Registered: July 2009
Junior Member
This was the reason.
Thank you Sebastian.
Re: Testing the Grammar using the Parser and existing data set [message #519154 is a reply to message #513285] Sun, 07 March 2010 08:26 Go to previous messageGo to next message
Matthieu  is currently offline Matthieu
Messages: 10
Registered: February 2010
Junior Member
Hello,
I've the same problem but the solution you previously gave doesn't work in my project. Here is an extract of what I have (the grammar is called "Asms") :

public class MyProcAssembler  implements Assembler {
	
	private Injector injector;
	
	public MyProcAssembler() {
		AsmsStandaloneSetup asmsSetup = new AsmsStandaloneSetup();
		injector = asmsSetup.createInjectorAndDoEMFRegistration();
	}
	
	public Program load(String filename) {
		ResourceSet set = injector.get(XtextResourceSet.class);
		Resource res = set.getResource(URI.createURI(filename), true);
		IParseResult result = ((XtextResource)res).getParseResult();
                EObject root = result.getRootASTElement();
		return buildProgram((fr.ifsic.m1info.sptk.asms.Program)root); 
	}
...
}


I guess "Injector" is "com.google.inject.Injector" (there is another Injector proposed by eclipse but it's not that returned by createInjectorAndDoEMFRegistration).
The problem is that Eclipse says there is no "get" method for injector.

Any idea ?
Thanks !

Matthieu

EDIT: actually, problem solved, it was just "getInstance" instead of "get".

[Updated on: Sun, 07 March 2010 08:32]

Report message to a moderator

Re: Testing the Grammar using the Parser and existing data set [message #519163 is a reply to message #519154] Sun, 07 March 2010 10:18 Go to previous messageGo to next message
Sven Efftinge is currently offline Sven Efftinge
Messages: 1667
Registered: July 2009
Senior Member
Hi Matthieu,

please use #getInstance(Class<?>) instead.

Sven

Matthieu schrieb:
> Hello,
> I've the same problem but the solution you previously gave doesn't work
> in my project. Here is an extract of what I have (the grammar is called
> "Asms") :
>
> public class MyProcAssembler implements Assembler {
>
> private Injector injector;
>
> public MyProcAssembler() {
> AsmsStandaloneSetup asmsSetup = new AsmsStandaloneSetup();
> injector = asmsSetup.createInjectorAndDoEMFRegistration();
> }
>
> public Program load(String filename) {
> ResourceSet set = injector.get(XtextResourceSet.class);
> Resource res = set.getResource(URI.createURI(filename), true);
> IParseResult result = ((XtextResource)res).getParseResult();
> EObject root = result.getRootASTElement();
> return buildProgram((fr.ifsic.m1info.sptk.asms.Program)root); }
> ...
> }
>
> I guess "Injector" is "com.google.inject.Injector" (there is another
> Injector proposed by eclipse but it's not that returned by
> createInjectorAndDoEMFRegistration).
> The problem is that Eclipse says there is no "get" method for injector.
>
> Any idea ?
> Thanks !
>
> Matthieu
>


--
Need professional support for Xtext and EMF?
Go to: http://xtext.itemis.com
Twitter : @svenefftinge
Blog : blog.efftinge.de


--
Need professional support for Xtext and EMF?
Go to: http://xtext.itemis.com
Twitter : @svenefftinge
Blog : blog.efftinge.de
Re: Testing the Parser using existing data set [message #537296 is a reply to message #513869] Tue, 01 June 2010 16:04 Go to previous messageGo to next message
eyrieowl is currently offline eyrieowl
Messages: 6
Registered: May 2010
Junior Member
And how about if you wanted to parse an in-memory String? Is there a way in which ResourceSet would play a role? Or is the only way to accomplish that by using the parser directly? Thanks!
Re: Testing the Parser using existing data set [message #537344 is a reply to message #537296] Wed, 02 June 2010 02:23 Go to previous message
Sven Efftinge is currently offline Sven Efftinge
Messages: 1667
Registered: July 2009
Senior Member
eyrieowl schrieb:
> And how about if you wanted to parse an in-memory String? Is there a
> way in which ResourceSet would play a role? Or is the only way to
> accomplish that by using the parser directly? Thanks!

Resource res = set.createResource(URI.createURI("file.name"));
res.load(new StringInputStream(inMemoryString), null);

will do.

Sven

--
Need professional support for Xtext and EMF?
Go to: http://xtext.itemis.com
Twitter : @svenefftinge
Blog : blog.efftinge.de


--
Need professional support for Xtext and EMF?
Go to: http://xtext.itemis.com
Twitter : @svenefftinge
Blog : blog.efftinge.de
Previous Topic:ANTLR Works question
Next Topic:questions about ResourceSetReferencingResourceSet
Goto Forum:
  


Current Time: Wed May 22 03:56:05 EDT 2013

Powered by FUDForum. Page generated in 0.01760 seconds