Skip to content

Instantly share code, notes, and snippets.

@abuiles
Created October 30, 2009 16:39
Show Gist options
  • Save abuiles/222508 to your computer and use it in GitHub Desktop.
Save abuiles/222508 to your computer and use it in GitHub Desktop.
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