Created
October 30, 2009 16:39
-
-
Save abuiles/222508 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
grammar Textuml; | |
options{output=AST;} | |
tokens{ | |
ATTRIBUTE; | |
CLASS; | |
CLASS_DEF; | |
FEATURE; | |
IN; | |
OPERATION; | |
OUT; | |
PACKAGE; | |
PACKAGE_DECL; | |
PACKAGE_ID; | |
PRIMITIVE; | |
PROFILE_ID; | |
SIGNATURE; | |
STEREOTYPE; | |
VISIBILITY; | |
} | |
// START :members | |
@header { | |
package org.textuml.grammar; | |
import java.util.Vector; | |
} | |
@members { | |
private Vector <String> classAttributes = new Vector (); | |
private Vector <String> classNames = new Vector (); | |
private Vector <String> classOperations = new Vector (); | |
private Vector <String> primitives = new Vector (); | |
private Vector <String> usedSymbols = new Vector (); | |
public ArrayList<String> messages = new ArrayList<String>(); | |
private void addSymbol (String symbol){ | |
if (!usedSymbols.contains (symbol)) | |
usedSymbols.add ( symbol ); | |
} | |
} | |
//END :members | |
start :( package_heading namespace_content{ | |
for (String symbol : usedSymbols ) { | |
if (!primitives.contains (symbol)) | |
if (!classNames.contains (symbol)) | |
messages.add ("Cannot find symbol " + symbol); | |
} | |
} | |
| profile_heading profile_content | |
) | |
END! DOT!; | |
package_heading : PACKAGE IDENTIFIER SEMICOLON -> ^(PACKAGE_ID IDENTIFIER); | |
profile_heading : PROFILE IDENTIFIER SEMICOLON -> ^(PROFILE_ID IDENTIFIER); | |
profile_content : stereotype*; | |
stereotype : STEREOTYPE IDENTIFIER EXTENDS UML COLON COLON stereotype_super END SEMICOLON -> ^(STEREOTYPE IDENTIFIER stereotype_super); | |
stereotype_super : SCLASS | PPROPERTY; | |
namespace_content : top_level_element*; | |
top_level_element : top_level_element_choice; | |
top_level_element_choice : class_def | primitive_def ; | |
primitive_def : PRIMITIVE IDENTIFIER{ | |
if ( primitives.contains($IDENTIFIER.text) ) { | |
messages.add("Primitive \"" + $IDENTIFIER.text + "\" already defined" ); | |
}else { | |
primitives.add($IDENTIFIER.text); | |
} | |
}SEMICOLON -> ^(PRIMITIVE IDENTIFIER) ; | |
class_def : class_header{ | |
classOperations.clear(); | |
classAttributes.clear(); | |
} | |
feature_decl_list? END SEMICOLON ->^(CLASS class_header feature_decl_list*); | |
class_header : class_type IDENTIFIER{ | |
if (classNames.contains($IDENTIFIER.text)) | |
messages.add("Class \"" + $IDENTIFIER.text + "\" already defined" ); | |
else | |
classNames.add($IDENTIFIER.text); | |
} -> IDENTIFIER; | |
class_type: CLASS ; | |
feature_decl_list : feature_decl feature_decl_list? ; | |
feature_decl : modifiers feature_type -> ^(FEATURE modifiers* feature_type) ; | |
modifiers : modifier_list?; | |
modifier_list : modifier; | |
modifier : visibility_modifier ; | |
visibility_modifier : PUBLIC -> PUBLIC | |
| PRIVATE -> PRIVATE ; | |
feature_type : operation_decl -> operation_decl | |
| attribute_decl -> attribute_decl ; | |
attribute_decl : ATTRIBUTE IDENTIFIER{ | |
if (classAttributes.contains ($IDENTIFIER.text)) | |
messages.add ("Class Attribute " + $IDENTIFIER.text + " is already defined"); | |
else | |
classAttributes.add ($IDENTIFIER.text); | |
} | |
COLON type_identifier SEMICOLON -> ^(ATTRIBUTE IDENTIFIER type_identifier); | |
type_identifier: IDENTIFIER{ | |
addSymbol ($IDENTIFIER.text); | |
}; | |
operation_decl : operation_header ; | |
operation_header: OPERATION IDENTIFIER{ | |
if (classOperations.contains ($IDENTIFIER.text)) | |
messages.add ("Class operation " + $IDENTIFIER.text + " is already defined"); | |
else | |
classOperations.add ($IDENTIFIER.text); | |
} | |
signature SEMICOLON -> ^(OPERATION IDENTIFIER signature) ; | |
signature : L_PAREN param_decl_list? R_PAREN optional_return_type? -> ^(SIGNATURE param_decl_list? optional_return_type?) ; | |
optional_return_type : COLON type_identifier -> ^(OUT type_identifier) ; | |
param_decl_list : param_decl param_decl_list_tail? ; | |
param_decl_list_tail : COMMA! param_decl param_decl_list_tail?; | |
param_decl : IDENTIFIER COLON type_identifier -> ^(IN IDENTIFIER type_identifier) ; | |
//Tokens | |
APPLY : 'apply' ; | |
ATTRIBUTE : 'attribute' ; | |
CLASS : 'class' ; | |
END : 'end' ; | |
EXTENDS : 'extends' ; | |
OPERATION : 'operation' ; | |
PACKAGE : 'package' ; | |
SCLASS : 'Class' ; | |
PRIMITIVE : 'primitive' ; | |
PRIVATE : 'private' ; | |
PROFILE : 'profile' ; | |
PPROPERTY : 'Property' ; | |
PUBLIC : 'public' ; | |
STEREOTYPE : 'stereotype' ; | |
UML : 'uml' ; | |
// separator symbols | |
COLON : ':' ; | |
COMMA : ',' ; | |
DOT : '.' ; | |
L_PAREN : '(' ; | |
R_PAREN : ')' ; | |
OPEN_SQ_BRACKET : '[' ; | |
CLOSE_SQ_BRACKET : ']' ; | |
SEMICOLON : ';' ; | |
//Helpers | |
IDENTIFIER : ( ANY_LETTER ) (ANY_LETTER |UNDERSCORE |DIGIT )* ; | |
fragment | |
ANY_LETTER | |
: 'A'..'Z' | 'a'..'z'; | |
fragment | |
DIGIT : '0'..'9'; | |
UNDERSCORE | |
: '_'; | |
WS : ( ' ' | '\t' | '\r' | '\n' )+ { $channel = HIDDEN; } ; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment