You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2014/07/22 15:36:14 UTC

[48/51] [partial] - Migrated the directory structure to a more Maven style structure. - Started migrating the Parser from Antlr2+3 and JFlex to Antlr4.

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/antlr2/org/apache/flex/compiler/internal/parsing/as/ImportMetadataTokenTypes.txt
----------------------------------------------------------------------
diff --git a/compiler/src/main/antlr2/org/apache/flex/compiler/internal/parsing/as/ImportMetadataTokenTypes.txt b/compiler/src/main/antlr2/org/apache/flex/compiler/internal/parsing/as/ImportMetadataTokenTypes.txt
new file mode 100644
index 0000000..478e80d
--- /dev/null
+++ b/compiler/src/main/antlr2/org/apache/flex/compiler/internal/parsing/as/ImportMetadataTokenTypes.txt
@@ -0,0 +1,68 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+Metadata // output token type name
+EOF=1
+TOKEN_NUMBER=4
+TOKEN_EQUALS=5
+TOKEN_ID=6
+TOKEN_VALUE=7
+TOKEN_STRING=8
+TOKEN_EVENT_KEYWORD = 9
+TOKEN_EFFECT_KEYWORD = 10
+TOKEN_STYLE_KEYWORD = 11
+TOKEN_ICONFILE_KEYWORD = 12
+TOKEN_ARRAYELEMENTTYPE_KEYWORD = 13
+TOKEN_DEFAULTPROPERTY_KEYWORD = 14
+TOKEN_BINDABLE_KEYWORD = 15
+TOKEN_INSTANCETYPE_KEYWORD = 16
+TOKEN_NONCOMMITTINGCHANGE_KEYWORD = 17
+TOKEN_EMBED_KEYWORD = 18
+TOKEN_INSPECTABLE_KEYWORD = 19
+TOKEN_NAME = 20
+TOKEN_OPEN_PAREN = 21
+TOKEN_CLOSE_PAREN = 22
+TOKEN_OPEN_BRACE = 23
+TOKEN_CLOSE_BRACE = 24
+TOKEN_UNKNOWN_KEYWORD = 25
+TOKEN_ATTR_NAME = 26
+TOKEN_ATTR_EVENT = 27
+TOKEN_ATTR_FORMAT = 28
+TOKEN_ATTR_TYPE = 29
+TOKEN_ATTR_ARRAY_TYPE = 30
+TOKEN_ATTR_INHERITS = 31
+TOKEN_ATTR_ENUM = 32
+TOKEN_ATTR_UNKNOWN = 33
+TOKEN_ATTR_ENV = 34
+TOKEN_ATTR_VERBOSE = 35
+TOKEN_ATTR_CATEGORY = 36
+TOKEN_ATTR_VARIABLE = 37
+TOKEN_ATTR_DEFAULT_VALUE = 38
+HIDDEN_TOKEN_NEWLINE=45
+HIDDEN_TOKEN_LETTER=46
+HIDDEN_TOKEN_DIGIT=47
+HIDDEN_TOKEN_HEX_DIGIT=48
+HIDDEN_TOKEN_ID_FIRST=49
+TOKEN_ATTR_STATES=50
+TOKEN_ATTR_IMPLEMENTATION=51
+TOKEN_ACCESSIBILITY_KEYWORD=52
+TOKEN_STATES_KEYWORD=53
+TOKEN_SKIN_STATES_KEYWORD=54
+TOKEN_ASDOC_COMMENT = 55
+TOKEN_HOST_COMPONENT_KEYWORD = 56
+TOKEN_RESOURCEBUNDLE_KEYWORD = 59
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/antlr2/org/apache/flex/compiler/internal/parsing/as/MetadataParser.g
----------------------------------------------------------------------
diff --git a/compiler/src/main/antlr2/org/apache/flex/compiler/internal/parsing/as/MetadataParser.g b/compiler/src/main/antlr2/org/apache/flex/compiler/internal/parsing/as/MetadataParser.g
new file mode 100644
index 0000000..f0c14ef
--- /dev/null
+++ b/compiler/src/main/antlr2/org/apache/flex/compiler/internal/parsing/as/MetadataParser.g
@@ -0,0 +1,397 @@
+header
+{
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.parsing.as;
+
+/*
+ * This file is generated from MetadataParser.g.
+ * DO NOT MAKE EDITS DIRECTLY TO THIS FILE.  THEY WILL BE LOST WHEN THE FILE IS GENERATED AGAIN!!!
+ */
+
+import java.util.HashMap;
+
+import antlr.NoViableAltException;
+import antlr.ParserSharedInputState;
+import antlr.RecognitionException;
+import antlr.Token;
+import antlr.TokenBuffer;
+import antlr.TokenStream;
+import antlr.TokenStreamException;
+import antlr.collections.impl.BitSet;
+
+import org.apache.flex.compiler.internal.tree.as.IdentifierNode;
+import org.apache.flex.compiler.internal.tree.as.metadata.*; 
+
+import org.apache.flex.compiler.tree.metadata.IMetaTagNode;
+import org.apache.flex.compiler.constants.IMetaAttributeConstants;
+
+}
+
+// MetadataParser parses a bunch of metadata attrs for a single node
+// (var, class, etc.) and makes up some tables of what it found.
+class MetadataParser extends Parser("org.apache.flex.compiler.internal.parsing.as.BaseMetaTagParser");
+options
+{
+	importVocab = ImportMetadata;
+	exportVocab = Metadata;
+}
+
+meta[MetaTagsNode parent]
+{
+	MetaTagNode tag = null;
+}
+	: ( asDocComment | openBrace : TOKEN_OPEN_BRACE 
+	( tag = event[parent]
+	| tag = effect[parent]
+	| tag = style[parent]
+	| tag = eventTrigger[parent]
+	| tag = typedTag[parent]
+	| tag = inspectable[parent]
+	| tag = defaultproperty[parent]
+	| tag = accessibilityClass[parent]
+	| tag = multiValue[parent]
+	| tag = skinClass[parent]
+	| tag = alternative[parent]
+	| tag = resourcebundle[parent]	
+	| tag = other[parent]
+	)
+	(closeBrace : TOKEN_CLOSE_BRACE
+	| closeParen : TOKEN_CLOSE_PAREN )*
+	)*
+	{
+		afterTag(tag, openBrace, closeBrace, closeParen);
+	}	
+	;
+
+asDocComment : docToken: TOKEN_ASDOC_COMMENT 
+	{
+		handleComment(docToken);
+	}
+	;
+	
+event[MetaTagsNode parent] returns [EventTagNode node]
+	{ 	
+		node = new EventTagNode();
+		}
+	: TOKEN_EVENT_KEYWORD 
+		(TOKEN_ATTR_NAME ( nameString: TOKEN_STRING { node.setName(build(nameString)); } )
+		| TOKEN_ATTR_TYPE (typeString: TOKEN_STRING { node.setEvent(typeString); } ) 
+		| unknownProperty[node]
+		| TOKEN_OPEN_PAREN {}
+		)*
+	{	
+		applyComment(node);
+		parent.addTag(node);
+		return node;
+	}
+	;
+	
+effect[MetaTagsNode parent] returns [EffectTagNode node]
+	{ 
+		node = new EffectTagNode();
+	}
+	: TOKEN_EFFECT_KEYWORD 
+		(TOKEN_ATTR_NAME ( nameString: TOKEN_STRING { node.setName(build(nameString)); } )
+		| TOKEN_ATTR_EVENT (typeString: TOKEN_STRING { node.setEvent(build(typeString)); } ) 
+		| unknownProperty[node]
+		| TOKEN_OPEN_PAREN {}
+		)*
+	{	
+			
+		applyComment(node);
+		parent.addTag(node);
+	
+	}
+	;
+
+style[MetaTagsNode parent] returns [StyleTagNode node]
+	{ 	
+		node = new StyleTagNode();
+		}
+	: TOKEN_STYLE_KEYWORD 
+		(TOKEN_ATTR_NAME ( nameString: TOKEN_STRING { node.setName(build(nameString)); } )
+		| TOKEN_ATTR_TYPE ( typeString: TOKEN_STRING { node.setType(typeString); } )
+		| TOKEN_ATTR_ARRAY_TYPE ( arrayTypeToken: TOKEN_STRING { node.setArrayType(build(arrayTypeToken)); } )
+		| TOKEN_ATTR_INHERITS ( boolType: TOKEN_STRING { node.setIsInheritable(getText(boolType)); } )
+		| TOKEN_ATTR_FORMAT ( formatToken: TOKEN_STRING { node.setFormat(getText(formatToken).trim()); } )
+		| TOKEN_ATTR_ENUM ( valuesToken : TOKEN_STRING { node.parseValues(getText(valuesToken).trim()); } )
+		| TOKEN_ATTR_STATES ( statesToken : TOKEN_STRING { node.parseStates(getText(statesToken).trim()); } )
+		| unknownProperty[node]
+		| TOKEN_OPEN_PAREN {}
+		)*
+	{	
+		applyComment(node);
+		parent.addTag(node);
+	}
+	;
+	
+inspectable[MetaTagsNode parent] returns [InspectableTagNode node]
+	{ 	
+		IdentifierNode type = null;
+		IdentifierNode var = null;
+		IdentifierNode arrayType = null;
+		node = new InspectableTagNode();
+		resetComments(node.getTagName());
+		}
+		
+	: TOKEN_INSPECTABLE_KEYWORD 
+		(TOKEN_ATTR_NAME ( nameToken: TOKEN_STRING { node.setName( getText(nameToken).trim() ); } )
+		| TOKEN_ATTR_ARRAY_TYPE ( atypeToken : TOKEN_STRING { node.setArrayType(build(atypeToken)); } )
+		| TOKEN_ATTR_TYPE ( typeToken : TOKEN_STRING { node.setType(typeToken); } )
+		| TOKEN_ATTR_VARIABLE ( varToken : TOKEN_STRING { node.setVariable(build(varToken)); } )
+		| TOKEN_ATTR_FORMAT ( formatToken : TOKEN_STRING { node.setFormat( getText(formatToken).trim() ); } )
+		| TOKEN_ATTR_ENUM ( valuesToken : TOKEN_STRING { node.parseValues( getText(valuesToken).trim() ); } )
+		| TOKEN_ATTR_CATEGORY ( catToken : TOKEN_STRING { node.setCategory( getText(catToken).trim()); } )
+		| TOKEN_ATTR_DEFAULT_VALUE ( defaultToken : TOKEN_STRING { node.setDefaultValue( getText(defaultToken).trim()); } )
+		| TOKEN_ATTR_VERBOSE ( verToken : TOKEN_STRING { node.setVerbose(getText(verToken).trim()); } )
+		| TOKEN_ATTR_ENV ( envToken : TOKEN_STRING {node.setEnvironment(getText(envToken).trim()); } )
+		| unknownProperty[node]
+		| TOKEN_OPEN_PAREN {}
+		)*
+	{	
+		parent.addTag(node);
+	}
+	;
+	
+eventTrigger[MetaTagsNode parent] returns [EventTriggerTagNode node]
+	{ 	
+		node = null;
+		IdentifierNode event = null;
+		String name = null;
+	}
+	: ( name = eventTriggerSet) {
+		resetComments(name);
+		node = new EventTriggerTagNode(name);
+	}
+		(TOKEN_ATTR_EVENT (eventToken: TOKEN_STRING { event = build(eventToken); if(event != null) { node.setEventName(event); }} )
+		| unknownProperty[node]
+		| TOKEN_OPEN_PAREN {}
+		)*
+	{	
+		parent.addTag(node);
+	}
+	;
+	
+eventTriggerSet returns [String value]
+	{
+		value = null;
+	}
+	: bk : TOKEN_BINDABLE_KEYWORD
+		{
+			value = bk.getText();
+		}
+	| nck : TOKEN_NONCOMMITTINGCHANGE_KEYWORD
+		{
+			value = nck.getText();
+		}
+	;
+	
+
+typedTag[MetaTagsNode parent] returns [TypedTagNode node]
+	{ 	
+		node = null;
+		IdentifierNode type = null;
+		String name = null;
+	}
+	: (name = typedTagSet)
+		{
+			node = new TypedTagNode(name);
+			resetComments(name);
+		}
+		( typeToken:TOKEN_STRING 
+		  { node.setTypeName(null, typeToken); }
+		| TOKEN_OPEN_PAREN {})*
+	{	
+		parent.addTag(node);
+	}
+	;
+	
+skinClass[MetaTagsNode parent] returns [SkinClassTagNode node]
+	{ 	
+		node = null;
+		IdentifierNode type = null;
+		String name = null;
+		node = new SkinClassTagNode();
+		resetComments(node.getTagName());
+	}
+	: TOKEN_SKINCLASS_KEYWORD
+		( TOKEN_ATTR_TYPE typeToken:TOKEN_STRING 
+		  { node.setTypeName(IMetaAttributeConstants.NAME_EVENT_TYPE, typeToken); }
+		| unknownProperty[node]
+		| TOKEN_OPEN_PAREN {}
+		)*
+	{	
+		parent.addTag(node);
+	}
+	;
+	
+alternative[MetaTagsNode parent] returns [AlternativeTagNode node]
+	{ 	
+		node = null;
+		IdentifierNode type = null;
+		String name = null;
+		node = new AlternativeTagNode();
+		resetComments(node.getTagName());
+	}
+	: TOKEN_ALTERNATIVE_KEYWORD
+		( TOKEN_ATTR_TYPE typeToken:TOKEN_STRING 
+		  { node.setTypeName(IMetaAttributeConstants.NAME_ALTERNATIVE_REPLACEMENT, typeToken); }
+		| unknownProperty[node]
+		| TOKEN_OPEN_PAREN {}
+		)*
+	{	
+		parent.addTag(node);
+	}
+	;
+	
+typedTagSet returns [String value]
+	{
+		value = null;
+	}
+	: ik : TOKEN_INSTANCETYPE_KEYWORD
+		{
+			value = ik.getText();
+		}
+	| hck : TOKEN_HOST_COMPONENT_KEYWORD
+		{
+			value = hck.getText();
+		}
+	| aek : TOKEN_ARRAYELEMENTTYPE_KEYWORD
+		{
+			value = aek.getText();
+		}
+	;
+	
+multiValue[MetaTagsNode parent] returns [MultiValueMetaTagNode node]
+	{ 	
+		String state = null;
+		node = null;
+		String name = null;
+	}
+	: (name = mvSet) 
+		{
+			node = new MultiValueMetaTagNode(name);
+			resetComments(name);
+		}
+		(stateToken: TOKEN_STRING { state = getText(stateToken); if(state != null) { node.addValue(state); state = null;}}
+		| TOKEN_OPEN_PAREN {})*
+	{	
+		parent.addTag(node);
+	}
+	;
+	
+mvSet returns [String value]
+	{
+		value = null;
+	}
+	: bk : TOKEN_STATES_KEYWORD
+		{
+			value = bk.getText();
+		}
+	| nck : TOKEN_SKIN_STATES_KEYWORD
+		{
+			value = nck.getText();
+		}
+	;
+	
+accessibilityClass[MetaTagsNode parent] returns [AccessibilityTagNode node]
+	{ 	
+		IdentifierNode type = null;
+		IdentifierNode name = null;
+		node = new AccessibilityTagNode();
+		resetComments(node.getTagName());	
+	}
+	: TOKEN_ACCESSIBILITY_KEYWORD 
+		(TOKEN_ATTR_IMPLEMENTATION nameString:TOKEN_STRING
+		 { node.setTypeName(IMetaAttributeConstants.NAME_ACCESSIBILITY_IMPLEMENTATION, nameString);}
+		| TOKEN_OPEN_PAREN {})*
+	{	parent.addTag(node); }
+	;
+	
+	
+defaultproperty[MetaTagsNode parent] returns [DefaultPropertyTagNode node]
+	{ 	
+		IdentifierNode type = null;
+		node = new DefaultPropertyTagNode();
+		resetComments(node.getTagName());
+	}
+	: TOKEN_DEFAULTPROPERTY_KEYWORD 
+		(typeToken: TOKEN_STRING { type = build(typeToken); if(type != null) { node.setPropertyNameNode(type); }}
+		| TOKEN_OPEN_PAREN {})*
+	{	
+		parent.addTag(node);
+	}
+	;
+	
+resourcebundle[MetaTagsNode parent] returns [ResourceBundleTagNode node]
+	{ 	
+		IdentifierNode bundleNameNode = null;
+		node = new ResourceBundleTagNode();
+		resetComments(node.getTagName());
+	}
+	: TOKEN_RESOURCEBUNDLE_KEYWORD 
+		( {LA(1) == TOKEN_STRING}? bundleToken:TOKEN_STRING { bundleNameNode = build(bundleToken); if(bundleNameNode != null) { node.setBundleNameNode(bundleNameNode); }}
+		| unknownProperty[node]
+		| unknownTypeAttribute[node]
+		| TOKEN_OPEN_PAREN {})*
+	{	
+		parent.addTag(node);
+	}
+	;
+	
+unknownTypeAttribute[MetaTagNode node]
+	: (TOKEN_ATTR_TYPE typeToken:TOKEN_STRING)
+	{
+		final String val = typeToken.getText();
+		if(val != null)
+		{
+			node.addToMap(IMetaAttributeConstants.NAME_EVENT_TYPE, val);
+		}
+	}
+	;
+	
+other[MetaTagsNode parent] returns [MetaTagNode node]
+	{
+		String name = "";
+		node = null; 
+	}
+		: keyWord : TOKEN_UNKNOWN_KEYWORD 
+			{ name = getText(keyWord); node = new BasicMetaTagNode(name); resetComments(name); } 
+		( unknownProperty[node]
+		| TOKEN_OPEN_PAREN {}
+		)*
+		{
+			parent.addTag(node);
+		}
+	
+	;
+
+unknownProperty[MetaTagNode node]
+    { 
+    	String attr = null; 
+    }
+    :( attrName:TOKEN_ATTR_UNKNOWN 
+    	{ attr = getText(attrName); }
+    )? 
+    
+    stringVal:TOKEN_STRING 
+		{ node.addToMap(attr, getText(stringVal)); } 
+    ;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/antlr3/org/apache/flex/compiler/internal/css/CSS.g
----------------------------------------------------------------------
diff --git a/compiler/src/main/antlr3/org/apache/flex/compiler/internal/css/CSS.g b/compiler/src/main/antlr3/org/apache/flex/compiler/internal/css/CSS.g
new file mode 100644
index 0000000..074bff3
--- /dev/null
+++ b/compiler/src/main/antlr3/org/apache/flex/compiler/internal/css/CSS.g
@@ -0,0 +1,520 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+/**
+ * This is a grammar for advanced CSS in Flex. It parses the CSS document and
+ * generate DOM objects.
+ */
+grammar CSS;
+
+options 
+{
+    language = Java;
+    output = AST;
+    k = 2;
+}
+
+tokens
+{ 
+    I_RULES; I_MEDIUM_CONDITIONS; I_DECL; I_RULE; I_SELECTOR_GROUP; I_SELECTOR; 
+    I_SIMPLE_SELECTOR; I_ARRAY; 
+}
+
+@header 
+{
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.css;
+
+import java.util.Map;
+import java.util.HashMap;
+import org.apache.flex.compiler.problems.CSSParserProblem;
+}
+
+@lexer::header 
+{
+package org.apache.flex.compiler.internal.css;
+
+import org.apache.flex.compiler.problems.CSSParserProblem;
+} 
+
+@lexer::members
+{
+
+/**
+ * Lexer problems.
+ */
+protected List<CSSParserProblem> problems = new ArrayList<CSSParserProblem>();
+
+/**
+ * Collect lexer problems.
+ */
+@Override
+public void displayRecognitionError(String[] tokenNames, RecognitionException e)
+{
+    problems.add(CSSParserProblem.create(this, tokenNames, e));
+}
+}
+
+@members 
+{
+
+/**
+ * Parser problems.
+ */
+protected List<CSSParserProblem> problems = new ArrayList<CSSParserProblem>();
+
+/**
+ * Collect parser problems.
+ */
+@Override
+public void displayRecognitionError(String[] tokenNames, RecognitionException e)
+{
+    problems.add(CSSParserProblem.create(this, tokenNames, e));
+}
+
+/**
+ * Check if the cursor is at the end of a simple selector.
+ */
+private final boolean endOfSimpleSelector()
+{
+    final CommonToken nextToken = (CommonToken) getTokenStream().LT(1);
+    if (nextToken == null)
+        return true;
+    
+    // Check if there's white space between the previous token and the next token.
+    final CommonToken lastToken = (CommonToken) getTokenStream().LT(-1);
+    if (lastToken != null && nextToken != null)
+    {
+        final int lastStop = lastToken.getStopIndex();
+        final int nextStart = nextToken.getStartIndex();
+        if (lastStop + 1 < nextStart)
+        {
+            return true;
+        }
+    }
+    
+    // If the next token is "{" or ",", it's also end of a selector.
+    final int nextType = nextToken.getType();
+    if (nextType == BLOCK_OPEN || nextType == COMMA)
+    {
+        return true;
+    }
+    
+    return false;
+}
+
+}
+
+/**
+ * Root rule for a CSS file.
+ */
+stylesheet
+    :   ( namespaceStatement | fontFace | mediaQuery | ruleset )*
+    ;
+
+/**
+ * This rule matches an "@namespace" statement.
+ *  
+ * For example, declaring a namespace prefix:
+ * @namespace mx "library://ns.adobe.com/flex/mx";
+ *
+ * Declaring the default namespace:
+ * @namespace "library://ns.adobe.com/flex/spark";
+ */
+namespaceStatement
+    :   AT_NAMESPACE ID? STRING SEMI_COLONS    
+    	->	^(AT_NAMESPACE ID? STRING)
+    ;
+  
+/**
+ * This rule matches a media query block.
+ * 
+ * For example:
+ * @media all { ... }
+ *
+ * A media query block can have one or many rulesets inside.
+ */
+mediaQuery
+    :   AT_MEDIA medium BLOCK_OPEN ruleset* BLOCK_END
+    	->	^(AT_MEDIA medium ruleset*)
+    ;
+  
+/**
+ * This rule matches the actual Flex media query conditions.
+ * For example: (application-dpi: 240) and (os-platform: "Android")
+ */
+medium 
+    :   mediumCondition    
+        (  
+            // Flex only support "and" at the momement. (Shaoting)
+            'and' 
+            mediumCondition 
+        )*
+        ->	^(I_MEDIUM_CONDITIONS mediumCondition*)
+    ;
+  
+/**
+ * This rule matches a media query condition expression. It is either a 
+ * word (like "all", "screen") or an expression like "(....)".
+ */
+mediumCondition
+    :   ID 			
+    |   ARGUMENTS
+    ;
+    
+/**
+ * For example:
+ *
+ * @font-face {
+ *     src: url("../assets/MyriadWebPro.ttf");
+ *     fontFamily: myFontFamily;
+ *     advancedAntiAliasing: true;
+ * }
+ *
+ * @see http://livedocs.adobe.com/flex/3/html/help.html?content=fonts_04.html
+ */    
+fontFace
+    :   AT_FONT_FACE declarationsBlock	-> ^(AT_FONT_FACE declarationsBlock)
+    ;
+  
+/**
+ * This rule matches a CSS Ruleset.
+ */
+ruleset
+    :   selectorGroup declarationsBlock
+        -> ^(I_RULE selectorGroup declarationsBlock)
+    ;
+
+/**
+ * This rule matches a group of comma-separated selectors.
+ */
+selectorGroup
+	:	compoundSelector ( COMMA compoundSelector )*  
+        ->	^(I_SELECTOR_GROUP compoundSelector+)
+    ;    
+
+/**
+ * Compound selector is a chain of simple selectors connected by combinators.
+ * Each compound selector has one "subject", which is the element name of the
+ * right most simple selector in the chain.
+ * 
+ * Currently, only descendant combinator (space) is supported.
+ * If we need to support combinators, add the terminals in this production.
+ * 
+ * For example:
+ * s|VBox s|HBox.content s|Button
+ */
+compoundSelector
+@init 
+{
+	final List<Object> simpleSelectorNodeList = new ArrayList<Object>();
+	Object currentSimpleSelectorNode = adaptor.create(I_SIMPLE_SELECTOR, "I_SIMPLE_SELECTOR");
+	Token simpleSelectorStartToken = null;
+    Token simpleSelectorStopToken = null;
+}
+@after 
+{
+	for(final Object simpleSelectorNode : simpleSelectorNodeList)
+		adaptor.addChild($compoundSelector.tree, simpleSelectorNode);
+}
+    :   (   l=simpleSelectorFraction 
+			{ 
+			    // expand token range of the current simple selector
+				if (simpleSelectorStartToken == null)
+				    simpleSelectorStartToken = $l.start;
+				simpleSelectorStopToken = $l.stop;
+				
+				adaptor.addChild(currentSimpleSelectorNode, $l.tree);
+				
+			    if (endOfSimpleSelector()) 
+			    {
+			        adaptor.setTokenBoundaries(
+                        currentSimpleSelectorNode,
+                        simpleSelectorStartToken,
+                        simpleSelectorStopToken);
+			    	simpleSelectorNodeList.add(currentSimpleSelectorNode);
+                        
+                    simpleSelectorStartToken = null;
+                    simpleSelectorStopToken = null;
+                    
+			    	currentSimpleSelectorNode = adaptor.create(I_SIMPLE_SELECTOR, "I_SIMPLE_SELECTOR");			   
+			    }
+			}
+        )+
+        ->	^(I_SELECTOR)   
+        // Tree nodes for simple selectors are added in the @after block.
+    ;
+    
+/**
+ * A compound selector consists of one or many simple selectors.
+ * This rule matches a fraction of a simple selector.
+ *
+ *   s|HBox s|Button.confirm #activeLabel,  <-- compound selector
+ *   s|HBox               <-- simple selector
+ *   s|Button.confirm     <-- simple selector
+ *   #activeLabel         <-- simple selector
+ *
+ * This rule will match each of the following 4 fractions:
+ *
+ *   [s|HBox] [s|Button] [.confirm] [#activeLabel]
+ *
+ * As you can see, the parse tree isn't aware of the start and end of a simple
+ * selector. This is because white spaces have been ignored so that the parser 
+ * can't distinguish between the following input:
+ *
+ *   s|Button.rounded .labelText   <-- 2 simple selectors
+ *   s|Button.rounded.labelText    <-- 1 simple selector
+ * 
+ * As a result, this rule could match only part of a simple selector, because
+ * the conditions were broken into multiple tokens.
+ */  
+simpleSelectorFraction
+    :   element
+    |   condition 
+    ;
+   
+/**
+ * This rule matches a condition selector.
+ * For example: ".styleName", "#loginButton", ":up"
+ */
+condition
+    :   ( DOT^ ID
+        | HASH_WORD 
+        | COLON^ ID 
+        ) 
+    ;
+  
+/** 
+ * This rule matches an element name with or without namespace prefix. It also
+ * matches the special "any" element "*".
+ * For example: "s|Panel", "Label", "*"
+ */
+element
+    :   ID PIPE^ ID
+    |   ID          
+    |   STAR            
+    ;
+    
+/**
+ * This rule matches a declarations block.
+ * For example:
+ * { font-size:12; font-family: "sans"; }
+ */    
+declarationsBlock
+    :   BLOCK_OPEN 
+        (   
+            SEMI_COLONS?   // multiple semi-colons are legal
+            declaration 
+            ( 
+                SEMI_COLONS 
+                declaration
+            )* 
+            SEMI_COLONS? 
+        )?
+        BLOCK_END
+        ->	^(I_DECL declaration*)
+    ;
+
+/**
+ * This rule matches property declaration. The declaration is a key value pair.
+ * For example:
+ * font-size:12px
+ */  
+declaration
+    :   ID COLON value	->	^(COLON ID value)
+    ;
+    
+/**
+ * This rule matches an array of property values or a single value.
+ * If it matches an array, the output is an I_ARRAY tree of element values.
+ * If it matches an single value, the output is a "singleValue" tree.
+ * 
+ * Array example:
+ *     2.0, 2.0, 3.0, 3.0
+ *     "tl", "tr", "bl", "br"
+ *     #FFFFFF, #FFFFFF, #FFFFFF, #FFFFFF
+ *     Verdana, Times, Sans-Serif
+ *     solid 1px #666666
+ *
+ */    
+value  
+@init { int count = 1; }
+    :   singleValue ( COMMA? singleValue { count++; } )*
+        -> {count > 1}? ^(I_ARRAY singleValue+)
+        ->              singleValue
+    ;  
+  
+/**
+ * This rule matches one property value.
+ *
+ * For example:
+ *     12, 12px, 100%.
+ *     #FF3322
+ *     rgb(100%, 100%, 100%)
+ *     ClassReference("mx.controls.Button")
+ *     PropertyReference("size")
+ *     Embed(source="assets/logo.png", mimeType="images/png")
+ *     url("../fonts/myfont.ttf")
+ *     local("My Font")
+ *     "Times New Roman"
+ *     italic
+ */
+singleValue
+    :   NUMBER_WITH_UNIT
+    |   HASH_WORD
+    |   CLASS_REFERENCE ARGUMENTS
+    								-> ^(CLASS_REFERENCE ARGUMENTS)
+    |   PROPERTY_REFERENCE ARGUMENTS
+    								-> ^(PROPERTY_REFERENCE ARGUMENTS)
+    |   EMBED ARGUMENTS
+    								-> ^(EMBED ARGUMENTS)
+    |   URL ARGUMENTS			    -> ^(URL ARGUMENTS)
+    |   LOCAL ARGUMENTS		        -> ^(LOCAL ARGUMENTS)
+    |   RGB
+    |   STRING						
+    |   ID 
+    ;
+
+/* Lexer Rules */
+  
+BLOCK_OPEN : '{' ;
+BLOCK_END :  '}' ;
+COMMA : ',' ;
+PERCENT : '%' ;
+PIPE : '|' ; 
+STAR : '*' ;
+DOT : '.' ;
+EQUALS: '='; 
+AT_NAMESPACE : '@namespace' ;
+AT_MEDIA : '@media' ;
+COLON : ':' ;
+AT_FONT_FACE : '@font-face' ;
+CLASS_REFERENCE : 'ClassReference' ;
+PROPERTY_REFERENCE : 'PropertyReference' ;
+EMBED : 'Embed' ;
+URL : 'url' ;
+LOCAL : 'local' ;
+NULL : 'null' ;
+
+/** 
+ * Matches a rgb definition - rgb(100%,100%,100%)
+ */
+RGB : 	'rgb(' 	( WS* NUMBER ( PERCENT | ) WS* ) ',' 
+				( WS* NUMBER ( PERCENT | ) WS* ) ',' 
+				( WS* NUMBER ( PERCENT | ) WS* ) 
+		')' ; 
+
+/** Arguments of a function call property value. */
+ARGUMENTS
+    :   '(' ( options {greedy=false;}: . )* ')'
+    ; 
+/**
+ * Match multiple semi-colons in Lexer level so that the parser can have a 
+ * finite number of look ahead, instead of LL(*);
+ */
+SEMI_COLONS : ';'+ ;
+
+/**
+ * Matches either ID selector or color value. Unfortunately, these two types of
+ * tokens are ambiguous in ANTLR world.
+ */
+HASH_WORD
+    :   '#' ( LETTER | DIGIT | '-' | '_' )+
+    ;
+  
+ID  :   ( '-' | '_'  )? LETTER ( LETTER | DIGIT | '-' | '_'  )*
+    ;
+    
+fragment
+LETTER
+    :   'a'..'z' 
+    |   'A'..'Z'
+    ;
+
+/**
+ * Matches: 100, -100, +3.14, .25, -0.25, +.25
+ */
+fragment
+NUMBER
+	:   ('+'|'-')? 
+		(	DIGIT+ (DOT DIGIT+)? 
+		|   DOT DIGIT+
+		)
+    ;    
+
+/**
+ * Matches a number with optinal unit string.
+ * For example:
+ *   2.5
+ *   2.5em
+ *   100%
+ *
+ * The grammar doesn't allow spaces between the number and the unit.
+ * For example: 35 em is a "NUMBER" and an "ID".
+ * Otherwise such input will be ambigiuous:
+ *    font-style: bold 35 pt 25em
+ * "pt" could either be another keyword or the unit of "35".
+ */
+NUMBER_WITH_UNIT
+	:	NUMBER (ID|PERCENT)?
+	;
+	
+fragment
+DIGIT
+    :   '0'..'9' 
+    ;
+  
+COMMENT
+    :   '/*' ( options {greedy=false;}: . )* '*/' 
+        { $channel = HIDDEN; }
+    ;
+
+WS  :   ( ' ' | '\t' | '\r' | '\n' )  { $channel = HIDDEN; }
+    ;
+
+STRING
+    :   STRING_QUOTE 
+        ( ~( '\\' | STRING_QUOTE ) )* 
+        STRING_QUOTE
+    ;
+  
+fragment
+STRING_QUOTE
+    :   '"'
+    |   '\''
+    ;
+

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/antlr3/org/apache/flex/compiler/internal/css/CSSTree.g
----------------------------------------------------------------------
diff --git a/compiler/src/main/antlr3/org/apache/flex/compiler/internal/css/CSSTree.g b/compiler/src/main/antlr3/org/apache/flex/compiler/internal/css/CSSTree.g
new file mode 100644
index 0000000..59d241e
--- /dev/null
+++ b/compiler/src/main/antlr3/org/apache/flex/compiler/internal/css/CSSTree.g
@@ -0,0 +1,338 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+/**
+ * This is a tree grammar for advanced CSS in Flex. It walks the AST generated 
+ * by the CSS parser and builds CSS DOM objects.
+ */
+tree grammar CSSTree;
+
+options 
+{
+    language = Java;
+    tokenVocab = CSS;
+    ASTLabelType = CommonTree;
+}
+
+@header 
+{
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+	
+package org.apache.flex.compiler.internal.css;
+
+import java.util.Map;
+import java.util.HashMap;
+import org.apache.flex.compiler.css.*;
+import org.apache.flex.compiler.problems.CSSParserProblem;
+
+}
+
+@members 
+{
+
+/**
+ * CSS DOM object.
+ */
+protected CSSDocument model;
+
+/**
+ * Every definition object needs the token stream to compute source location.
+ */
+private final TokenStream tokenStream = getTreeNodeStream().getTokenStream();
+
+/**
+ * Tree walker problems.
+ */
+protected List<CSSParserProblem> problems = new ArrayList<CSSParserProblem>();
+
+/**
+ * Collect problems.
+ */
+@Override
+public void displayRecognitionError(String[] tokenNames, RecognitionException e)
+{
+    problems.add(CSSParserProblem.create(this, tokenNames, e));
+}
+}
+
+stylesheet
+scope 
+{
+    // namespace declarations are buffered in this map
+    List<CSSNamespaceDefinition> namespaces;
+    // ruleset definitions are buffered in this list
+    List<CSSRule> rules;
+    // font-face declarations are buffered in this list
+    List<CSSFontFace> fontFaces;
+}
+@init 
+{
+    $stylesheet::rules = new ArrayList<CSSRule>();
+    $stylesheet::namespaces = new ArrayList<CSSNamespaceDefinition>();
+    $stylesheet::fontFaces = new ArrayList<CSSFontFace>();
+}
+@after 
+{
+    model = new CSSDocument($stylesheet::rules, 
+                            $stylesheet::namespaces, 
+                            $stylesheet::fontFaces,
+                            $start,
+                            tokenStream);
+}
+    :   ( namespaceStatement | fontFace | mediaQuery | ruleset )*
+    ;
+
+namespaceStatement
+@after        
+{ 
+    final CSSNamespaceDefinition ns = new CSSNamespaceDefinition(
+            $id.text, $uri.text, $start, tokenStream);
+    $stylesheet::namespaces.add(ns); 
+}
+    :   ^(AT_NAMESPACE id=ID? uri=STRING)
+    ;
+  
+mediaQuery
+scope 
+{ 
+    // media query condition clauses are buffered in this list
+    List<CSSMediaQueryCondition> conditions 
+}
+@init 
+{ 
+    $mediaQuery::conditions = new ArrayList<CSSMediaQueryCondition>(); 
+}
+    :   ^(AT_MEDIA medium ruleset*)
+    ;
+  
+medium 
+    :   ^(I_MEDIUM_CONDITIONS mediumCondition*)
+    ;
+  
+mediumCondition
+@after 
+{ 
+    $mediaQuery::conditions.add(new CSSMediaQueryCondition($start, tokenStream)); 
+} 
+    :   ID | ARGUMENTS
+    ;
+    
+fontFace
+@after
+{
+    final CSSFontFace fontFace = new CSSFontFace($d.properties, $start, tokenStream);
+    $stylesheet::fontFaces.add(fontFace);
+}
+    :   ^(AT_FONT_FACE d=declarationsBlock)
+    ;
+  
+ruleset
+scope 
+{
+    // list of subject selectors
+    List<CSSSelector> subjects
+}
+@init 
+{
+    $ruleset::subjects = new ArrayList<CSSSelector>();
+}
+@after 
+{
+    final List<CSSMediaQueryCondition> mediaQueryConditions;
+    if ($mediaQuery.isEmpty())
+        mediaQueryConditions = null;
+    else
+        mediaQueryConditions = $mediaQuery::conditions;
+    
+    final CSSRule cssRule = new CSSRule(
+            mediaQueryConditions,
+            $ruleset::subjects,
+            $d.properties, 
+            $start, 
+            tokenStream);
+    $stylesheet::rules.add(cssRule);
+}
+    :   ^(I_RULE selectorGroup d=declarationsBlock)
+    ;
+
+selectorGroup
+    :  ^(I_SELECTOR_GROUP compoundSelector+)
+    ;    
+
+compoundSelector
+@init
+{
+    final Stack<CSSSelector> simpleSelectorStack = new Stack<CSSSelector>();
+}
+@after
+{
+    $ruleset::subjects.add(simpleSelectorStack.peek());
+}
+    :   ^(I_SELECTOR simpleSelector[simpleSelectorStack]+)   
+    ;
+    
+simpleSelector [Stack<CSSSelector> simpleSelectorStack]
+scope
+{
+    String namespace;
+    String element;
+    List<CSSSelectorCondition> conditions;
+}
+@init
+{
+    $simpleSelector::conditions = new ArrayList<CSSSelectorCondition>();
+    final CSSCombinator combinator ;
+    if (simpleSelectorStack.isEmpty())
+        combinator = null;
+    else                    
+        combinator = new CSSCombinator(simpleSelectorStack.peek(), CombinatorType.DESCENDANT, $start, tokenStream);
+}
+@after
+{
+    final CSSSelector simpleSelector = new CSSSelector(
+        combinator,
+        $simpleSelector::element,
+        $simpleSelector::namespace,
+        $simpleSelector::conditions, 
+        $start, 
+        tokenStream);
+    simpleSelectorStack.push(simpleSelector);
+}
+    :   ^(I_SIMPLE_SELECTOR simpleSelectorFraction+)
+    ;    
+    
+simpleSelectorFraction
+    :   elementSelector
+    |   conditionSelector 
+    ;
+   
+conditionSelector
+@init
+{
+    ConditionType type = null;
+    String name = null;
+}
+@after
+{
+    $simpleSelector::conditions.add(
+        new CSSSelectorCondition(name, type, $start, tokenStream));
+}
+    :   ^(DOT c=ID)   { type = ConditionType.CLASS; name = $c.text; }  
+    |   HASH_WORD   { type = ConditionType.ID; name = $HASH_WORD.text.substring(1); }
+    |   ^(COLON s=ID) { type = ConditionType.PSEUDO; name = $s.text; } 
+    ;
+  
+elementSelector
+    :   ^(PIPE ns=ID e1=ID)  
+        { $simpleSelector::element = $e1.text; 
+          $simpleSelector::namespace = $ns.text; }
+    |   e2=ID             
+        { $simpleSelector::element = $e2.text; }
+    |   STAR           
+        { $simpleSelector::element = $STAR.text; }
+    ;
+    
+declarationsBlock returns [List<CSSProperty> properties]
+@init 
+{
+    $properties = new ArrayList<CSSProperty>();
+}
+    :   ^(I_DECL (declaration 
+         { 
+             if ($declaration.property != null)
+                 $properties.add($declaration.property); 
+         }
+         )*)
+    ;
+
+declaration returns [CSSProperty property]
+@after
+{
+    if ($id.text != null && $v.propertyValue != null)
+        $property = new CSSProperty($id.text, $v.propertyValue, $start, tokenStream);  
+}
+    :   ^(COLON id=ID v=value)
+    ;
+    
+value returns [CSSPropertyValue propertyValue]
+    :   ^( I_ARRAY 
+                              { final List<CSSPropertyValue> array = new ArrayList<CSSPropertyValue>(); }
+           ( s1=singleValue   { array.add($s1.propertyValue); } )+
+        )                     { $propertyValue = new CSSArrayPropertyValue(array, $start, tokenStream); }
+    |   s2=singleValue        { $propertyValue = $s2.propertyValue; }
+    ;    
+  
+singleValue returns [CSSPropertyValue propertyValue]
+    :   NUMBER_WITH_UNIT         
+		{ $propertyValue = new CSSNumberPropertyValue($NUMBER_WITH_UNIT.text, $start, tokenStream); }
+    |   HASH_WORD         
+        { $propertyValue = new CSSColorPropertyValue($start, tokenStream); }
+    |   RGB
+    	{ $propertyValue = new CSSRgbColorPropertyValue($RGB.text, $start, tokenStream); }
+    |   ^(CLASS_REFERENCE cr=ARGUMENTS)
+        { $propertyValue = new CSSFunctionCallPropertyValue($CLASS_REFERENCE.text, $cr.text, $start, tokenStream); }
+    |   ^(PROPERTY_REFERENCE pr=ARGUMENTS)
+        { $propertyValue = new CSSFunctionCallPropertyValue($PROPERTY_REFERENCE.text, $pr.text, $start, tokenStream); }
+    |   ^(EMBED es=ARGUMENTS)
+        { $propertyValue = new CSSFunctionCallPropertyValue($EMBED.text, $es.text, $start, tokenStream); }
+    |   ^(URL url=ARGUMENTS)
+        { $propertyValue = new CSSFunctionCallPropertyValue($URL.text, $url.text, $start, tokenStream); }
+    |   ^(LOCAL l=ARGUMENTS)
+        { $propertyValue = new CSSFunctionCallPropertyValue($LOCAL.text, $l.text, $start, tokenStream); }
+    |   s=STRING   
+        { $propertyValue = new CSSStringPropertyValue($s.text, $start, tokenStream); }                   
+    |   ID
+        { $propertyValue = CSSKeywordPropertyValue.create($start, tokenStream); } 
+    ;
+    
+argumentList returns [List<String> labels, List<String> values]
+@init 
+{
+    $labels = new ArrayList<String>(3);
+    $values = new ArrayList<String>(3);
+}
+    :   argument[$labels, $values]+
+    ;
+    
+argument [List<String> labels, List<String> values]
+@after
+{
+    // Use null for argument without label.
+    $labels.add($l.text);
+    $values.add($v.text); 
+}
+    :   ^(EQUALS l=ID? v=STRING)
+    ;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/antlr4/org/apache/flex/compiler/internal/css/CSS.g4
----------------------------------------------------------------------
diff --git a/compiler/src/main/antlr4/org/apache/flex/compiler/internal/css/CSS.g4 b/compiler/src/main/antlr4/org/apache/flex/compiler/internal/css/CSS.g4
new file mode 100644
index 0000000..61f42a9
--- /dev/null
+++ b/compiler/src/main/antlr4/org/apache/flex/compiler/internal/css/CSS.g4
@@ -0,0 +1,514 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+/**
+ * This is a grammar for advanced CSS in Flex. It parses the CSS document and
+ * generate DOM objects.
+ */
+grammar CSS;
+
+options 
+{
+    language = Java;
+//    output = AST;
+//    k = 2;
+}
+
+tokens
+{
+    I_RULES, I_MEDIUM_CONDITIONS, I_DECL, I_RULE, I_SELECTOR_GROUP, I_SELECTOR,
+    I_SIMPLE_SELECTOR, I_ARRAY
+}
+
+@header
+{
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.apache.flex.compiler.problems.CSSParserProblem;
+}
+
+/*@lexer::header
+{
+package org.apache.flex.compiler.internal.css;
+
+import org.apache.flex.compiler.problems.CSSParserProblem;
+}
+
+@lexer::members
+{
+
+ * Lexer problems.
+protected List<CSSParserProblem> problems = new ArrayList<CSSParserProblem>();
+
+ * Collect lexer problems.
+@Override
+public void displayRecognitionError(String[] tokenNames, RecognitionException e)
+{
+    problems.add(CSSParserProblem.create(this, tokenNames, e));
+}
+}*/
+
+@members 
+{
+
+/**
+ * Parser problems.
+ */
+/*protected List<CSSParserProblem> problems = new ArrayList<CSSParserProblem>();*/
+
+/**
+ * Collect parser problems.
+ */
+/*@Override
+public void displayRecognitionError(String[] tokenNames, RecognitionException e)
+{
+    problems.add(CSSParserProblem.create(this, tokenNames, e));
+}*/
+
+/**
+ * Check if the cursor is at the end of a simple selector.
+ */
+/*private final boolean endOfSimpleSelector()
+{
+    final CommonToken nextToken = (CommonToken) getTokenStream().LT(1);
+    if (nextToken == null)
+        return true;
+    
+    // Check if there's white space between the previous token and the next token.
+    final CommonToken lastToken = (CommonToken) getTokenStream().LT(-1);
+    if (lastToken != null && nextToken != null)
+    {
+        final int lastStop = lastToken.getStopIndex();
+        final int nextStart = nextToken.getStartIndex();
+        if (lastStop + 1 < nextStart)
+        {
+            return true;
+        }
+    }
+    
+    // If the next token is "{" or ",", it's also end of a selector.
+    final int nextType = nextToken.getType();
+    if (nextType == BLOCK_OPEN || nextType == COMMA)
+    {
+        return true;
+    }
+    
+    return false;
+}*/
+
+}
+
+/**
+ * Root rule for a CSS file.
+ */
+stylesheet
+    :   ( namespaceStatement | fontFace | mediaQuery | ruleset )*
+    ;
+
+/**
+ * This rule matches an "@namespace" statement.
+ *  
+ * For example, declaring a namespace prefix:
+ * @namespace mx "library://ns.adobe.com/flex/mx";
+ *
+ * Declaring the default namespace:
+ * @namespace "library://ns.adobe.com/flex/spark";
+ */
+namespaceStatement
+    :   AT_NAMESPACE ID? STRING SEMI_COLONS
+//    	->	^(AT_NAMESPACE ID? STRING)
+    ;
+  
+/**
+ * This rule matches a media query block.
+ * 
+ * For example:
+ * @media all { ... }
+ *
+ * A media query block can have one or many rulesets inside.
+ */
+mediaQuery
+    :   AT_MEDIA medium BLOCK_OPEN ruleset* BLOCK_END
+//    	->	^(AT_MEDIA medium ruleset*)
+    ;
+  
+/**
+ * This rule matches the actual Flex media query conditions.
+ * For example: (application-dpi: 240) and (os-platform: "Android")
+ */
+medium 
+    :   mediumCondition    
+        (  
+            // Flex only support "and" at the momement. (Shaoting)
+            'and' 
+            mediumCondition 
+        )*
+//        ->	^(I_MEDIUM_CONDITIONS mediumCondition*)
+    ;
+  
+/**
+ * This rule matches a media query condition expression. It is either a 
+ * word (like "all", "screen") or an expression like "(....)".
+ */
+mediumCondition
+    :   ID 			
+    |   ARGUMENTS
+    ;
+    
+/**
+ * For example:
+ *
+ * @font-face {
+ *     src: url("../assets/MyriadWebPro.ttf");
+ *     fontFamily: myFontFamily;
+ *     advancedAntiAliasing: true;
+ * }
+ *
+ * @see http://livedocs.adobe.com/flex/3/html/help.html?content=fonts_04.html
+ */    
+fontFace
+    :   AT_FONT_FACE declarationsBlock
+//        -> ^(AT_FONT_FACE declarationsBlock)
+    ;
+  
+/**
+ * This rule matches a CSS Ruleset.
+ */
+ruleset
+    :   selectorGroup declarationsBlock
+//        -> ^(I_RULE selectorGroup declarationsBlock)
+    ;
+
+/**
+ * This rule matches a group of comma-separated selectors.
+ */
+selectorGroup
+	:	compoundSelector ( COMMA compoundSelector )*  
+//        ->	^(I_SELECTOR_GROUP compoundSelector+)
+    ;    
+
+/**
+ * Compound selector is a chain of simple selectors connected by combinators.
+ * Each compound selector has one "subject", which is the element name of the
+ * right most simple selector in the chain.
+ * 
+ * Currently, only descendant combinator (space) is supported.
+ * If we need to support combinators, add the terminals in this production.
+ * 
+ * For example:
+ * s|VBox s|HBox.content s|Button
+ */
+compoundSelector
+@init 
+{
+	final List<Object> simpleSelectorNodeList = new ArrayList<Object>();
+	//Object currentSimpleSelectorNode = adaptor.create(I_SIMPLE_SELECTOR, "I_SIMPLE_SELECTOR");
+	Token simpleSelectorStartToken = null;
+    Token simpleSelectorStopToken = null;
+}
+/*@after
+{
+	for(final Object simpleSelectorNode : simpleSelectorNodeList)
+		adaptor.addChild($compoundSelector.tree, simpleSelectorNode);
+}*/
+    :   (   l=simpleSelectorFraction 
+/*			{
+			    // expand token range of the current simple selector
+				if (simpleSelectorStartToken == null)
+				    simpleSelectorStartToken = $l.start;
+				simpleSelectorStopToken = $l.stop;
+				
+				adaptor.addChild(currentSimpleSelectorNode, $l.tree);
+				
+			    if (endOfSimpleSelector()) 
+			    {
+			        adaptor.setTokenBoundaries(
+                        currentSimpleSelectorNode,
+                        simpleSelectorStartToken,
+                        simpleSelectorStopToken);
+			    	simpleSelectorNodeList.add(currentSimpleSelectorNode);
+                        
+                    simpleSelectorStartToken = null;
+                    simpleSelectorStopToken = null;
+                    
+			    	currentSimpleSelectorNode = adaptor.create(I_SIMPLE_SELECTOR, "I_SIMPLE_SELECTOR");			   
+			    }
+			}*/
+        )+
+//        ->	^(I_SELECTOR)
+        // Tree nodes for simple selectors are added in the @after block.
+    ;
+    
+/**
+ * A compound selector consists of one or many simple selectors.
+ * This rule matches a fraction of a simple selector.
+ *
+ *   s|HBox s|Button.confirm #activeLabel,  <-- compound selector
+ *   s|HBox               <-- simple selector
+ *   s|Button.confirm     <-- simple selector
+ *   #activeLabel         <-- simple selector
+ *
+ * This rule will match each of the following 4 fractions:
+ *
+ *   [s|HBox] [s|Button] [.confirm] [#activeLabel]
+ *
+ * As you can see, the parse tree isn't aware of the start and end of a simple
+ * selector. This is because white spaces have been ignored so that the parser 
+ * can't distinguish between the following input:
+ *
+ *   s|Button.rounded .labelText   <-- 2 simple selectors
+ *   s|Button.rounded.labelText    <-- 1 simple selector
+ * 
+ * As a result, this rule could match only part of a simple selector, because
+ * the conditions were broken into multiple tokens.
+ */  
+simpleSelectorFraction
+    :   element
+    |   condition 
+    ;
+   
+/**
+ * This rule matches a condition selector.
+ * For example: ".styleName", "#loginButton", ":up"
+ */
+condition
+    :   ( DOT ID
+        | HASH_WORD 
+        | COLON ID
+        ) 
+    ;
+  
+/** 
+ * This rule matches an element name with or without namespace prefix. It also
+ * matches the special "any" element "*".
+ * For example: "s|Panel", "Label", "*"
+ */
+element
+    :   ID PIPE ID
+    |   ID          
+    |   STAR            
+    ;
+    
+/**
+ * This rule matches a declarations block.
+ * For example:
+ * { font-size:12; font-family: "sans"; }
+ */    
+declarationsBlock
+    :   BLOCK_OPEN 
+        (   
+            SEMI_COLONS?   // multiple semi-colons are legal
+            declaration 
+            ( 
+                SEMI_COLONS 
+                declaration
+            )* 
+            SEMI_COLONS? 
+        )?
+        BLOCK_END
+//        ->	^(I_DECL declaration*)
+    ;
+
+/**
+ * This rule matches property declaration. The declaration is a key value pair.
+ * For example:
+ * font-size:12px
+ */  
+declaration
+    :   ID COLON value
+//    	->	^(COLON ID value)
+    ;
+    
+/**
+ * This rule matches an array of property values or a single value.
+ * If it matches an array, the output is an I_ARRAY tree of element values.
+ * If it matches an single value, the output is a "singleValue" tree.
+ * 
+ * Array example:
+ *     2.0, 2.0, 3.0, 3.0
+ *     "tl", "tr", "bl", "br"
+ *     #FFFFFF, #FFFFFF, #FFFFFF, #FFFFFF
+ *     Verdana, Times, Sans-Serif
+ *     solid 1px #666666
+ *
+ */    
+value  
+@init { int count = 1; }
+    :   singleValue ( COMMA? singleValue { count++; } )*
+//        -> {count > 1}? ^(I_ARRAY singleValue+)
+//        ->              singleValue
+    ;  
+  
+/**
+ * This rule matches one property value.
+ *
+ * For example:
+ *     12, 12px, 100%.
+ *     #FF3322
+ *     rgb(100%, 100%, 100%)
+ *     ClassReference("mx.controls.Button")
+ *     PropertyReference("size")
+ *     Embed(source="assets/logo.png", mimeType="images/png")
+ *     url("../fonts/myfont.ttf")
+ *     local("My Font")
+ *     "Times New Roman"
+ *     italic
+ */
+singleValue
+    :   NUMBER_WITH_UNIT
+    |   HASH_WORD
+    |   CLASS_REFERENCE ARGUMENTS
+//    								-> ^(CLASS_REFERENCE ARGUMENTS)
+    |   PROPERTY_REFERENCE ARGUMENTS
+//    								-> ^(PROPERTY_REFERENCE ARGUMENTS)
+    |   EMBED ARGUMENTS
+//    								-> ^(EMBED ARGUMENTS)
+    |   URL ARGUMENTS
+//    			    -> ^(URL ARGUMENTS)
+    |   LOCAL ARGUMENTS
+//    	        -> ^(LOCAL ARGUMENTS)
+    |   RGB
+    |   STRING						
+    |   ID 
+    ;
+
+/* Lexer Rules */
+  
+BLOCK_OPEN : '{' ;
+BLOCK_END :  '}' ;
+COMMA : ',' ;
+PERCENT : '%' ;
+PIPE : '|' ; 
+STAR : '*' ;
+DOT : '.' ;
+EQUALS: '='; 
+AT_NAMESPACE : '@namespace' ;
+AT_MEDIA : '@media' ;
+COLON : ':' ;
+AT_FONT_FACE : '@font-face' ;
+CLASS_REFERENCE : 'ClassReference' ;
+PROPERTY_REFERENCE : 'PropertyReference' ;
+EMBED : 'Embed' ;
+URL : 'url' ;
+LOCAL : 'local' ;
+NULL : 'null' ;
+
+/** 
+ * Matches a rgb definition - rgb(100%,100%,100%)
+ */
+RGB : 	'rgb(' 	( WS* NUMBER ( PERCENT | ) WS* ) ',' 
+				( WS* NUMBER ( PERCENT | ) WS* ) ',' 
+				( WS* NUMBER ( PERCENT | ) WS* ) 
+		')' ; 
+
+/** Arguments of a function call property value. */
+ARGUMENTS
+    :   '(' .*? ')'
+    ; 
+/**
+ * Match multiple semi-colons in Lexer level so that the parser can have a 
+ * finite number of look ahead, instead of LL(*);
+ */
+SEMI_COLONS : ';'+ ;
+
+/**
+ * Matches either ID selector or color value. Unfortunately, these two types of
+ * tokens are ambiguous in ANTLR world.
+ */
+HASH_WORD
+    :   '#' ( LETTER | DIGIT | '-' | '_' )+
+    ;
+  
+ID  :   ( '-' | '_'  )? LETTER ( LETTER | DIGIT | '-' | '_'  )*
+    ;
+    
+fragment
+LETTER
+    :   'a'..'z' 
+    |   'A'..'Z'
+    ;
+
+/**
+ * Matches: 100, -100, +3.14, .25, -0.25, +.25
+ */
+fragment
+NUMBER
+	:   ('+'|'-')? 
+		(	DIGIT+ (DOT DIGIT+)? 
+		|   DOT DIGIT+
+		)
+    ;    
+
+/**
+ * Matches a number with optinal unit string.
+ * For example:
+ *   2.5
+ *   2.5em
+ *   100%
+ *
+ * The grammar doesn't allow spaces between the number and the unit.
+ * For example: 35 em is a "NUMBER" and an "ID".
+ * Otherwise such input will be ambigiuous:
+ *    font-style: bold 35 pt 25em
+ * "pt" could either be another keyword or the unit of "35".
+ */
+NUMBER_WITH_UNIT
+	:	NUMBER (ID|PERCENT)?
+	;
+	
+fragment
+DIGIT
+    :   '0'..'9' 
+    ;
+  
+COMMENT
+    :   '/*' .*? '*/'
+    ;
+
+WS  :   ( ' ' | '\t' | '\r' | '\n' )
+    ;
+
+STRING
+    :   ['"''\']
+        ( ~( '\\' | ['"''\'] ) )*
+        ['"''\']
+    ;
+