refactored grammar and xtext metamodel

This commit is contained in:
sefftinge 2008-08-15 10:02:37 +00:00 committed by sefftinge
parent 0ecf2f16a3
commit 7dfbbf2398
7 changed files with 33 additions and 38 deletions

View file

@ -26,8 +26,8 @@ public class XtextGrammarTest extends AbstractGeneratorTest {
public void testInstantiate() throws Exception {
EObject grammar = (EObject) getModel("language foo generate foo 'bar' Foo : name=ID;");
assertWithXtend("'Foo'","parserRules.first().name",grammar);
assertWithXtend("'name'","parserRules.first().alternatives.feature",grammar);
assertWithXtend("'Foo'","rules.first().name",grammar);
assertWithXtend("'name'","rules.first().alternatives.feature",grammar);
}
}

View file

@ -11,11 +11,9 @@ language org.eclipse.xtext.XtextGrammarTest
generate XtextTest "http://www.eclipse.org/2008/Test/XtextTest"
Grammar :
((abstract?='abstract language' | 'language') idElements+=ID ('.' idElements+=ID)* ('extends' superGrammarIdElements+=ID ('.' superGrammarIdElements+=ID)*)?)?
(abstract?='abstract language' | 'language') idElements+=ID ('.' idElements+=ID)* ('extends' superGrammarIdElements+=ID ('.' superGrammarIdElements+=ID)*)?
metamodelDeclarations+=AbstractMetamodelDeclaration*
parserRules+=ParserRule*
('lexing' ':'
lexerRules+=LexerRule+)?
(rules+=AbstractRule)+
;
AbstractRule : LexerRule | ParserRule;
@ -29,9 +27,9 @@ GeneratedMetamodel :
ReferencedMetamodel :
'import' uri=STRING ('as' alias=ID)?;
LexerRule :
name=ID ('returns' type=TypeRef)? ':'
body=STRING
LexerRule :
('native'|'lexer') name=ID ('returns' type=TypeRef)? ':'
body=STRING ';'
;
ParserRule :
@ -43,6 +41,7 @@ ParserRule :
TypeRef :
(alias=ID '::')? name=ID
;
Alternatives returns AbstractElement:
Group ({Alternatives.groups+=current} '|' groups+=Group)*
;
@ -54,16 +53,20 @@ Group returns AbstractElement:
AbstractToken returns AbstractElement:
(Assignment |
Action |
AbstractTerminal) cardinality=('?'|'*'|'+')?;
AbstractTerminal) (cardinality=('?'|'*'|'+'))?;
Assignment returns Assignment:
feature=ID operator=('+='|'='|'?=') terminal=AbstractTerminal;
Action returns Action:
'{' ('current' '=')? typeName=TypeRef ('.' feature=ID operator=('='|'+=') 'current')? '}';
'{' ('current' '=')? typeName=TypeRef '.' feature=ID operator=('='|'+=') 'current' '}';//TODO make assignment optional
AbstractTerminal returns AbstractElement:
Keyword | RuleCall | ParenthesizedElement
Keyword | RuleCall | ParenthesizedElement | CrossReference
;
CrossReference :
'[' type=TypeRef ('|' rule=RuleCall)? ']'
;
ParenthesizedElement returns AbstractElement:
@ -76,9 +79,4 @@ Keyword :
RuleCall :
name=ID ;
// lexing:
// Problem: LEXER_BODY kann nicht in xtxt beschrieben werden, da das erste '#>' bereits matcht
// Lösung: built-in lexer token
// LEXER_BODY : <# '<#' ( options {greedy=false;} : . )* '#>' #>

View file

@ -5,8 +5,6 @@ import "classpath:/org/eclipse/xtext/grammarinheritance/ametamodel.ecore" as mm
InheritedParserRule returns mm::AType :
'element' name=ID;
lexing:
lexer REAL returns ecore::EDouble : "RULE_INT '.' RULE_INT";
REAL returns ecore::EDouble : "RULE_INT '.' RULE_INT";
ID : "('^')?('a'..'z'|'A'..'Z'|'ö'|'ä'|'ü'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*";
lexer ID : "('^')?('a'..'z'|'A'..'Z'|'ö'|'ä'|'ü'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*";

View file

@ -27,47 +27,47 @@ public class ParseErrorHandlingTest extends AbstractGeneratorTest {
}
public void testLexError() throws Exception {
EObject root = getModel("import 'holla' % as foo");
EObject root = getModel("language a import 'holla' % as foo");
EList<SyntaxError> errors = NodeUtil.getRootNode(root).allSyntaxErrors();
assertEquals(1,errors.size());
assertEquals("%", ((LeafNode)errors.get(0).getNode()).getText());
assertEquals(1, errors.get(0).getNode().getLine());
assertEquals(15, errors.get(0).getNode().getOffset());
assertEquals(26, errors.get(0).getNode().getOffset());
assertEquals(1, errors.get(0).getNode().getLength());
assertEquals(1, errors.size());
}
public void testParseError1() throws Exception {
EObject root = getModel("import 'holla' foo returns x::y::Z : name=ID;");
EObject root = getModel("language a 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().getLine());
assertEquals(31, errors.get(0).getNode().getOffset());
assertEquals(42, errors.get(0).getNode().getOffset());
assertEquals(2, errors.get(0).getNode().getLength());
assertEquals(1, errors.size());
}
public void testParseError2() throws Exception {
Object object = getModel("import 'holla' foo returns y::Z : name=ID #;");
assertWithXtend("'ID'", "parserRules.first().eAllContents.typeSelect(XtextTest::RuleCall).first().name", object);
Object object = getModel("language a import 'holla' foo returns y::Z : name=ID #;");
assertWithXtend("'ID'", "rules.first().eAllContents.typeSelect(XtextTest::RuleCall).first().name", object);
}
public void testParseError3() throws Exception {
Object object = getModel("import 'holla' foo returns y::Z : name=ID #############");
assertWithXtend("'ID'", "parserRules.first().eAllContents.typeSelect(XtextTest::RuleCall).first().name", object);
Object object = getModel("language a import 'holla' foo returns y::Z : name=ID #############");
assertWithXtend("'ID'", "rules.first().eAllContents.typeSelect(XtextTest::RuleCall).first().name", object);
}
public void testParseError4() throws Exception {
Object object = getModel("import 'holla' foo returns y::Z : name=ID # 'foo'; bar : 'stuff'");
Object object = getModel("language a import 'holla' foo returns y::Z : name=ID # 'foo'; bar : 'stuff'");
//System.out.println(errors);
assertWithXtend("'ID'", "parserRules.first().eAllContents.typeSelect(XtextTest::RuleCall).first().name", object);
assertWithXtend("null", "parserRules.first().eAllContents.typeSelect(XtextTest::Keyword).first().name", object);
assertWithXtend("'stuff'", "parserRules.get(1).eAllContents.typeSelect(XtextTest::Keyword).first().value", object);
assertWithXtend("'ID'", "rules.first().eAllContents.typeSelect(XtextTest::RuleCall).first().name", object);
assertWithXtend("null", "rules.first().eAllContents.typeSelect(XtextTest::Keyword).first().name", object);
assertWithXtend("'stuff'", "rules.get(1).eAllContents.typeSelect(XtextTest::Keyword).first().value", object);
}
public void testname() throws Exception {
String model = "import 'holla' foo returns y::Z : name=ID # 'foo'; bar : 'stuff'";
String model = "language a import 'holla' foo returns y::Z : name=ID # 'foo'; bar : 'stuff'";
for (int i=model.length();0<i;i--) {
getModel(model.substring(0, i));
}

View file

@ -15,5 +15,4 @@ Model :
Element:
name=ID h=STRING;
lexing:
STRING : " '#' ('B')+ ";
lexer STRING : " '#' ('B')+ ";

View file

@ -52,7 +52,7 @@ public class BootstrapModelTest extends AbstractGeneratorTest {
List<MetaModel> result = (List<MetaModel>) facade.call("getAllMetaModels", grammarModel);
MetaModel xtext = (MetaModel) invokeWithXtend("select(e|e.alias()==null).first()", result);
MetaModel ecore = (MetaModel) invokeWithXtend("select(e|e.alias()=='ecore').first()", result);
assertEquals(15,xtext.getTypes().size());
assertEquals(16,xtext.getTypes().size());
assertEquals(3,ecore.getTypes().size());
for(AbstractType t : xtext.getTypes()) {

View file

@ -38,7 +38,7 @@ public class XtextUtilTrafoTest extends AbstractGeneratorTest {
+ "Main : ^import+=Import* types+=Type*;"
+ "Import : 'import' uri=STRING;"
+ "Type : 'type' name=ID 'extends' ^extends=[Type];");
RuleCall rc = (RuleCall) invokeWithXtend("parserRules.first().eAllContents.typeSelect(xtext::RuleCall).first()", model);
RuleCall rc = (RuleCall) invokeWithXtend("rules.first().eAllContents.typeSelect(xtext::RuleCall).first()", model);
assertNotNull(rc);
assertWithXtend("'Main'", "testCurrentType().name", rc);
assertWithXtend("false", "testCurrentType().abstract", rc);