mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 00:38:56 +00:00
refactored grammar and xtext metamodel
This commit is contained in:
parent
0ecf2f16a3
commit
7dfbbf2398
7 changed files with 33 additions and 38 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;} : . )* '#>' #>
|
||||
|
|
|
@ -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')*";
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -15,5 +15,4 @@ Model :
|
|||
Element:
|
||||
name=ID h=STRING;
|
||||
|
||||
lexing:
|
||||
STRING : " '#' ('B')+ ";
|
||||
lexer STRING : " '#' ('B')+ ";
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue