partial parsing revisited

EContentAdapter for offset und line
This commit is contained in:
jkohnlein 2008-07-03 12:17:22 +00:00 committed by sefftinge
parent c2990c22d5
commit 71269b96a8
10 changed files with 141 additions and 109 deletions

View file

@ -31,8 +31,8 @@ public class ParseErrorHandlingTest extends AbstractGeneratorTest {
EList<SyntaxError> errors = NodeUtil.getRootNode(root).allSyntaxErrors();
assertEquals(1,errors.size());
assertEquals("%", ((LeafNode)errors.get(0).getNode()).getText());
assertEquals(1, errors.get(0).getNode().line());
assertEquals(15, errors.get(0).getNode().offset());
assertEquals(1, errors.get(0).getNode().getLine());
assertEquals(15, errors.get(0).getNode().getOffset());
assertEquals(1, errors.get(0).getNode().length());
assertEquals(1, errors.size());
}
@ -41,8 +41,8 @@ public class ParseErrorHandlingTest extends AbstractGeneratorTest {
EObject root = getModel("import 'holla' foo returns x::y::Z : name=ID;");
EList<SyntaxError> errors = NodeUtil.getRootNode(root).allSyntaxErrors();
assertEquals("::", ((LeafNode)errors.get(0).getNode()).getText());
assertEquals(1, errors.get(0).getNode().line());
assertEquals(31, errors.get(0).getNode().offset());
assertEquals(1, errors.get(0).getNode().getLine());
assertEquals(31, errors.get(0).getNode().getOffset());
assertEquals(2, errors.get(0).getNode().length());
assertEquals(1, errors.size());
}

View file

@ -19,7 +19,7 @@ import org.eclipse.xtext.util.EmfStructureComparator;
*/
public abstract class AbstractPartialParserTest extends AbstractGeneratorTest {
protected static final boolean DEBUG = false;
protected static final boolean DEBUG = true;
protected EmfStructureComparator comparator;
@Override

View file

@ -1,52 +0,0 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package org.eclipse.xtext.parser;
import static org.eclipse.xtext.parsetree.NodeUtil.dumpCompositeNodes;
import static org.eclipse.xtext.parsetree.NodeUtil.getCompositeChildren;
import java.util.List;
import org.eclipse.xtext.parsetree.CompositeNode;
import org.eclipse.xtext.testlanguages.LookaheadLanguageStandaloneSetup;
import org.eclipse.xtext.tests.AbstractGeneratorTest;
/**
* @author Jan Köhnlein - Initial contribution and API
*
*/
public class LookaheadTest extends AbstractGeneratorTest {
/* (non-Javadoc)
* @see org.eclipse.xtext.tests.AbstractGeneratorTest#setUp()
*/
@Override
protected void setUp() throws Exception {
super.setUp();
with(LookaheadLanguageStandaloneSetup.class);
}
public void testLookahead() throws Exception {
CompositeNode rootNode = getRootNode("bar a foo bar c b d foo bar b c");
dumpCompositeNodes("", rootNode);
assertEquals(0, rootNode.getLookahead());
List<CompositeNode> alts = getCompositeChildren(rootNode);
assertEquals(1, alts.get(0).getLookahead());
assertEquals(1, alts.get(1).getLookahead());
assertEquals(1, alts.get(2).getLookahead());
assertEquals(1, getCompositeChildren(alts.get(0)).get(0).getLookahead());
CompositeNode lookahead0 = getCompositeChildren(alts.get(1)).get(0);
assertEquals(3, lookahead0.getLookahead());
assertEquals(0, getCompositeChildren(lookahead0).get(0).getLookahead());
CompositeNode lookahead3 = getCompositeChildren(alts.get(2)).get(0);
assertEquals(3, lookahead3.getLookahead());
assertEquals(0, getCompositeChildren(lookahead3).get(0).getLookahead());
}
}

View file

@ -25,9 +25,9 @@ public class PartialParserReplaceTest extends AbstractPartialParserTest {
public void testExpression() throws Exception {
with(SimpleExpressionsStandaloneSetup.class);
String model = "(a+b+c)*(c/d)";
replaceAndReparse(model, 2, 2, "+hugo+egon", "a+hugo+egon+c");
replaceAndReparse(model, 2, 2, "+hugo+egon", "(a+hugo+egon+c)");
replaceAndReparse(model, 8, 5, "egon", "egon");
replaceAndReparse(model, 1, 2, "", "b+c");
replaceAndReparse(model, 1, 2, "", "(b+c)");
replaceAndReparse(model, 6, 3, "*", "(a+b+c*c/d)");
replaceAndReparse(model, 3, 1, "(x+y+z)", "(x+y+z)");
@ -40,7 +40,7 @@ public class PartialParserReplaceTest extends AbstractPartialParserTest {
public void testLookahead() throws Exception {
with(LookaheadLanguageStandaloneSetup.class);
String model = "foo bar b c";
replaceAndReparse(model, 10, 1, "d", " d");
replaceAndReparse(model, 10, 1, "d", "foo bar b d");
replaceAndReparse(model, 8, 1, "b", "foo bar b c");
replaceAndReparse(model, 0, model.length(), "", "");
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
* Copyright (c) NUM_ELEMENTS8 itemis AG (http://www.itemis.eu) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -18,15 +18,15 @@ import org.eclipse.xtext.testlanguages.SimpleExpressionsStandaloneSetup;
*/
public class PartialParsingPerformanceTest extends AbstractPartialParserTest {
public void testPerformance() throws Exception {
int magicnumber = 10;
private static final int NUM_ELEMENTS = 10;
public void testExpression() throws Exception {
with(SimpleExpressionsStandaloneSetup.class);
StringBuffer modelBuffer = new StringBuffer();
for(int i=0; i<magicnumber; ++i) {
for(int i=0; i<NUM_ELEMENTS; ++i) {
modelBuffer.append("(a+(b*");
}
modelBuffer.append("c");
for(int i=0; i<magicnumber; ++i) {
for(int i=0; i<NUM_ELEMENTS; ++i) {
modelBuffer.append(")+d)");
}
String model = modelBuffer.toString();
@ -35,4 +35,29 @@ public class PartialParsingPerformanceTest extends AbstractPartialParserTest {
assertTrue(reparse.getParseErrors() == null || reparse.getParseErrors().isEmpty());
}
// public void testReference() throws Exception {
// with(ReferenceGrammarStandaloneSetup.class);
// StringBuffer modelBuffer = new StringBuffer();
// modelBuffer.append("spielplatz 17 {\n");
// for(int i=0; i<NUM_ELEMENTS; ++i) {
// modelBuffer.append(" kind ( Herbert");
// modelBuffer.append(i);
// modelBuffer.append(" 11 )\n");
// }
// for(int i=0; i<NUM_ELEMENTS; ++i) {
// modelBuffer.append(" erwachsener ( Hugo");
// modelBuffer.append(i);
// modelBuffer.append(" 111 )\n");
// }
// modelBuffer.append(" erwachsener ( Sven 112 )\n");
// for(int i=0; i<NUM_ELEMENTS; ++i) {
// modelBuffer.append(" spielzeug ( Schaufel GRÜN )\n");
// }
// modelBuffer.append("}\n");
// String model = modelBuffer.toString();
// CompositeNode rootNode = getRootNode(model);
// IParseResult reparse = PartialParsingUtil.reparse(getParser(), rootNode, model.indexOf("Sven"), 4, "Peter");
// assertTrue(reparse.getParseErrors() == null || reparse.getParseErrors().isEmpty());
// }
}

View file

@ -18,6 +18,7 @@ import org.eclipse.xtext.parser.impl.PartialParsingPointers;
import org.eclipse.xtext.parser.impl.PartialParsingUtil;
import org.eclipse.xtext.parsetree.CompositeNode;
import org.eclipse.xtext.testlanguages.LookaheadLanguageStandaloneSetup;
import org.eclipse.xtext.testlanguages.ReferenceGrammarStandaloneSetup;
import org.eclipse.xtext.testlanguages.SimpleExpressionsStandaloneSetup;
/**
@ -29,25 +30,27 @@ public class PartialParsingPointerTest extends AbstractPartialParserTest {
public void testExpression() throws Exception {
with(SimpleExpressionsStandaloneSetup.class);
String model = "(a+b+c)*(c/d)";
PartialParsingPointers parsingPointers = calculatePartialParsingPointers(model, 1, 1);
checkParseRegionPointers(parsingPointers, "a+b+c", "ActionImpl", "Addition", "Op", "Op", "values");
PartialParsingPointers parsingPointers;
parsingPointers = calculatePartialParsingPointers(model, 1, 1);
checkParseRegionPointers(parsingPointers, "(a+b+c)", "Parens", "Parens", "Op", "Op", "values");
parsingPointers = calculatePartialParsingPointers(model, 3, 1);
checkParseRegionPointers(parsingPointers, "b", "Multiplication", "Multiplication", "Atom", "Op", "values");
parsingPointers = calculatePartialParsingPointers(model, 5, 2);
checkParseRegionPointers(parsingPointers, model, "Sequence", "Sequence", "Op", null, null);
checkParseRegionPointers(parsingPointers, "(a+b+c)", "Parens", "Parens", "Op", "Op", "values");
parsingPointers = calculatePartialParsingPointers(model, 6, 1);
checkParseRegionPointers(parsingPointers, model, "Sequence", "Sequence", "Op", null, null);
checkParseRegionPointers(parsingPointers, "(a+b+c)", "Parens", "Parens", "Op", "Op", "values");
parsingPointers = calculatePartialParsingPointers(model, 8, 2);
checkParseRegionPointers(parsingPointers, "(c/d)", "Term", "Term", "Op", "Op", "values");
parsingPointers = calculatePartialParsingPointers(model, 9, 2);
checkParseRegionPointers(parsingPointers, "c/d", "Addition", "Addition", "Op", "Op", "values");
checkParseRegionPointers(parsingPointers, "(c/d)", "Parens", "Parens", "Op", "Op", "values");
model="a b";
model = "a b";
parsingPointers = calculatePartialParsingPointers(model, 1, 1);
checkParseRegionPointers(parsingPointers, "a b", "ActionImpl", "Sequence", "Sequence", null, null);
}
@ -56,17 +59,47 @@ public class PartialParsingPointerTest extends AbstractPartialParserTest {
with(LookaheadLanguageStandaloneSetup.class);
String model = "bar a foo bar c b d foo bar b c";
for (int i = 0; i < model.length(); ++i) {
System.out.println(i);
PartialParsingPointers parsingPointers = calculatePartialParsingPointers(model, i, 1);
if (i < 29) {
if (i < 3) {
checkParseRegionPointers(parsingPointers, model, "Entry", "Entry", "Entry", null, null);
}
else if (i < 5) {
checkParseRegionPointers(parsingPointers, "bar a", "LookAhead0", "LookAhead0", "LookAhead0", "Entry",
"contents");
}
else if (i < 9) {
checkParseRegionPointers(parsingPointers, model, "Entry", "Entry", "Entry", null, null);
}
else if (i < 15) {
checkParseRegionPointers(parsingPointers, " foo bar c b d", "Alts", "Alts", "LookAhead1", "Entry",
"contents");
}
else if (i < 19) {
checkParseRegionPointers(parsingPointers, " foo bar c b d", "LookAhead1", "LookAhead1", "LookAhead1",
"Entry", "contents");
}
else if (i < 23) {
checkParseRegionPointers(parsingPointers, model, "Entry", "Entry", "Entry", null, null);
}
else if (i < 29) {
checkParseRegionPointers(parsingPointers, " foo bar b c", "Alts", "Alts", "LookAhead3", "Entry",
"contents");
}
else {
checkParseRegionPointers(parsingPointers, " c", "LookAhead4", "LookAhead4", "LookAhead4", "LookAhead3",
"z");
checkParseRegionPointers(parsingPointers, " foo bar b c", "LookAhead3", "LookAhead3", "LookAhead3", "Entry",
"contents");
}
}
}
public void testReference() throws Exception {
with(ReferenceGrammarStandaloneSetup.class);
String model = "spielplatz 17 { kind ( Dennis 6 ) kind ( Sven 7 ) }";
PartialParsingPointers parsingPointers = calculatePartialParsingPointers(model, model.indexOf("Sven"), 4);
checkParseRegionPointers(parsingPointers, " kind ( Sven 7 )", "Kind", "Kind", "Kind", "Spielplatz", "kinder");
}
private PartialParsingPointers calculatePartialParsingPointers(String model, int changeRegionStart,
int changeRegionSize) throws Exception {
CompositeNode rootNode = getRootNode(model);
@ -113,11 +146,14 @@ public class PartialParsingPointerTest extends AbstractPartialParserTest {
assertEquals(expectedAstParentElementClassName, astParentElementClassName);
String containmentFeatureName = parsingPointers.findASTContainmentFeatureName();
assertEquals(expectedAstParentFeatureName, containmentFeatureName);
if(astParentElement != null) {
EStructuralFeature containmentFeature = astParentElement.eClass().getEStructuralFeature(containmentFeatureName);
if(containmentFeature.isMany()) {
assertTrue(((List<EObject>) astParentElement.eGet(containmentFeature)).contains(parsingPointers.findASTReplaceElement()));
} else {
if (astParentElement != null) {
EStructuralFeature containmentFeature = astParentElement.eClass().getEStructuralFeature(
containmentFeatureName);
if (containmentFeature.isMany()) {
assertTrue(((List<EObject>) astParentElement.eGet(containmentFeature)).contains(parsingPointers
.findASTReplaceElement()));
}
else {
assertTrue(astParentElement.eGet(containmentFeature).equals(parsingPointers.findASTReplaceElement()));
}
}

View file

@ -21,23 +21,23 @@ public class LengthOffsetLineTest extends AbstractGeneratorTest {
CompositeNode node = (CompositeNode) getRootNode(model);
EList<LeafNode> leafNodes = node.getLeafNodes();
Iterator<LeafNode> iter = leafNodes.iterator();
assertEquals(0,iter.next().offset());
assertEquals(7,iter.next().offset());
assertEquals(8,iter.next().offset());
assertEquals(11,iter.next().offset());
assertEquals(12,iter.next().offset());
assertEquals(13,iter.next().offset());
assertEquals(20,iter.next().offset());
assertEquals(21,iter.next().offset());
assertEquals(24,iter.next().offset());
assertEquals(0,iter.next().getOffset());
assertEquals(7,iter.next().getOffset());
assertEquals(8,iter.next().getOffset());
assertEquals(11,iter.next().getOffset());
assertEquals(12,iter.next().getOffset());
assertEquals(13,iter.next().getOffset());
assertEquals(20,iter.next().getOffset());
assertEquals(21,iter.next().getOffset());
assertEquals(24,iter.next().getOffset());
}
public void testOffset2() throws Exception {
String model = "element foo;\nelement bar;";
CompositeNode node = (CompositeNode) getRootNode(model);
Iterator<AbstractNode> iter = node.getChildren().iterator();
assertEquals(0,iter.next().offset());
assertEquals(12,iter.next().offset());
assertEquals(0,iter.next().getOffset());
assertEquals(12,iter.next().getOffset());
assertFalse(iter.hasNext());
}
@ -46,15 +46,15 @@ public class LengthOffsetLineTest extends AbstractGeneratorTest {
CompositeNode node = (CompositeNode) getRootNode(model);
EList<LeafNode> leafNodes = node.getLeafNodes();
Iterator<LeafNode> iter = leafNodes.iterator();
assertEquals(1,iter.next().line());
assertEquals(1,iter.next().line());
assertEquals(1,iter.next().line());
assertEquals(1,iter.next().line());
assertEquals(1,iter.next().line());
assertEquals(2,iter.next().line());
assertEquals(2,iter.next().line());
assertEquals(2,iter.next().line());
assertEquals(2,iter.next().line());
assertEquals(1,iter.next().getLine());
assertEquals(1,iter.next().getLine());
assertEquals(1,iter.next().getLine());
assertEquals(1,iter.next().getLine());
assertEquals(1,iter.next().getLine());
assertEquals(2,iter.next().getLine());
assertEquals(2,iter.next().getLine());
assertEquals(2,iter.next().getLine());
assertEquals(2,iter.next().getLine());
assertFalse(iter.hasNext());
}
@ -62,12 +62,12 @@ public class LengthOffsetLineTest extends AbstractGeneratorTest {
String model = "element foo;\nelement bar;\nelement bar;\nelement bar;";
CompositeNode node = (CompositeNode) getRootNode(model);
Iterator<AbstractNode> iter = node.getChildren().iterator();
assertEquals(1,iter.next().line());
assertEquals(1,iter.next().getLine());
//Note: because preceding whitespace is added to the following node,
// the '\n' is always added to the following composite node
assertEquals(1,iter.next().line());
assertEquals(2,iter.next().line());
assertEquals(3,iter.next().line());
assertEquals(1,iter.next().getLine());
assertEquals(2,iter.next().getLine());
assertEquals(3,iter.next().getLine());
assertFalse(iter.hasNext());
}
@ -80,7 +80,7 @@ public class LengthOffsetLineTest extends AbstractGeneratorTest {
assertEquals(5,nodes.size());
int offset = 0;
for (LeafNode leafNode : nodes) {
assertEquals(offset,leafNode.offset());
assertEquals(offset,leafNode.getOffset());
offset += leafNode.length();
}
}

View file

@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package org.eclipse.xtext.parsetree;
import org.eclipse.xtext.testlanguages.ReferenceGrammarStandaloneSetup;
import org.eclipse.xtext.tests.AbstractGeneratorTest;
/**
* @author Jan Köhnlein - Initial contribution and API
*
*/
public class NodeContentAdapterTest extends AbstractGeneratorTest{
public void testNodeContentAdapter() throws Exception {
with(ReferenceGrammarStandaloneSetup.class);
CompositeNode rootNode = getRootNode("spielplatz 112 'Jajaja' { kind ( Dennis 7) }");
NodeUtil.dumpCompositeNodes("", rootNode);
}
}

View file

@ -9,8 +9,6 @@
package org.eclipse.xtext.parsetree.reconstr;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.parsetree.CompositeNode;
import org.eclipse.xtext.parsetree.IParseTreeConstructor;
import org.eclipse.xtext.parsetree.NodeUtil;
import org.eclipse.xtext.tests.AbstractGeneratorTest;

View file

@ -30,9 +30,9 @@ public class LeafNodeBug_234132 extends AbstractGeneratorTest {
System.out.println("Model length=" + model.length());
for (LeafNode leafNode : leafNodes) {
String text = leafNode.getText();
System.out.println("Leaf node" + leafNode.toString() + " offset=" + leafNode.offset() + " length=" + leafNode.length() + " text=" + ((text != null)? text : ""));
assertTrue(leafNode.length() + leafNode.offset() <= model.length());
assertEquals(model.substring(leafNode.offset(), leafNode.offset() + leafNode.length()), leafNode.getText());
System.out.println("Leaf node" + leafNode.toString() + " offset=" + leafNode.getOffset() + " length=" + leafNode.length() + " text=" + ((text != null)? text : ""));
assertTrue(leafNode.length() + leafNode.getOffset() <= model.length());
assertEquals(model.substring(leafNode.getOffset(), leafNode.getOffset() + leafNode.length()), leafNode.getText());
}
}
}