Skip to content

Instantly share code, notes, and snippets.

@matthew-n
Created December 18, 2014 23:03
Show Gist options
  • Save matthew-n/469d2a4f16644de1db75 to your computer and use it in GitHub Desktop.
Save matthew-n/469d2a4f16644de1db75 to your computer and use it in GitHub Desktop.
{
function extractOptional(optional, index) {
return optional ? optional[index] : null;
}
function optionalList(value) {
return value !== null ? value : [];
}
}
start
= ClassDeclaration*
/* ----- A.1 Lexical Grammar ----- */
SourceCharacter
= .
IdentifierStart
= [_a-z]i
IdentifierPart
= [_a-z0-9\.]i
HexDigit
= [0-9a-f]i
LineTerminator
= [\n\r\u2028\u2029]
LineTerminatorSequence "end of line"
= "\n"
/ "\r\n"
/ "\r"
/ "\u2028"
/ "\u2029"
WhiteSpace "whitespace"
= "\t"
/ "\v"
/ "\f"
/ " "
/ "\u00A0"
/ "\uFEFF"
Identifier
= !ReservedWord name:IdentifierName { return name; }
IdentifierName "identifier"
= first:IdentifierStart rest:IdentifierPart* {
return {
type: "Identifier",
name: first + rest.join("")
};
}
Comment
= "'" comment:$(!LineTerminator SourceCharacter)* {return comment;}
/* Litals */
StringLiteral "string"
= '"' chars:DoubleStringCharacter* '"' {
return { type: "Literal", value: chars.join("") };
}
DoubleStringCharacter
= !('"' / "\\" / LineTerminator) SourceCharacter { return text(); }
/ LineContinuation
SingleStringCharacter
= !("'" / "\\" / LineTerminator) SourceCharacter { return text(); }
/ LineContinuation
LineContinuation
= "\\" LineTerminatorSequence { return ""; }
NullLiteral
= NullToken { return { type: "Literal", value: null }; }
EmptyLiteral
= EmptyToken { return { type: "Literal", value: "empty" }; }
HexIntegerLiteral
= "#"i digits:$HexDigit+ {
return { type: "Literal", value: parseInt(digits, 16) };
}
/* Skipped */
__
= (WhiteSpace / LineTerminatorSequence / Comment)*
_
= (WhiteSpace)*
/* Words */
ReservedWord
= Commands
/ UMLObject
/ Annotation
/ EndToken
/ NullLiteral
/ EmptyLiteral
Commands
= HideToken
/ SetToken
UMLObject
= ClassToken
/ EnumToken
Annotation
= TitleToken
/ HeaderToken
/ FooterToken
/ LegendToken
/ NoteToken
ScopeModifier
= PrivateToken {return {type:"modifier", scope:"private"}; }
/ ProtectedToken {return {type:"modifier", scope:"protected"}; }
/ PackagePrivateToken {return {type:"modifier", scope:"package private"}; }
/ PublicToken {return {type:"modifier", scope:"public"}; }
/* Tokens */
NullToken = "null" !IdentifierPart
EmptyToken = "empty" !IdentifierPart
HideToken = "hide" !IdentifierPart
SetToken = "set" !IdentifierPart
EndToken = "end" !IdentifierPart
ClassToken = "class" !IdentifierPart
EnumToken = "enum" !IdentifierPart
PackageToken = "package" !IdentifierPart
TitleToken = "title " !IdentifierPart
HeaderToken = "header" !IdentifierPart
FooterToken = "footer" !IdentifierPart
LegendToken = "legend" !IdentifierPart
NoteToken = "note" !IdentifierPart
PrivateToken = "-"
ProtectedToken = "#"
PackagePrivateToken = "~"
PublicToken = "+"
StereotypeOpenToken = "<<"
StereotypeCloseToken = ">>"
LeftExtendsToken = "<|" !IdentifierPart
RightExtendsToken = "|>" !IdentifierPart
RightArrowToken = ">" !IdentifierPart
LeftArrowToken = "<" !IdentifierPart
CompositionToken = "o" !IdentifierPart
AggregationToken = "*" !IdentifierPart
SolidLineToken = "-" !IdentifierPart
BrokenLineToken = "." !IdentifierPart
/* ----- A.2 Number Conversions ----- */
/* Irrelevant. */
/* ----- A.3 Expressions ----- */
RelationshipBody
= SolidLineToken
/ BrokenLineToken
RelationshipLeftEnd
= LeftExtendsToken {return {type:"relation end", value: "left extend", directional: true}}
/ LeftArrowToken {return {type:"relation end", value: "left arrow", directional: true}}
/ CompositionToken {return {type:"relation end", value: "composition", directional: false}}
/ AggregationToken {return {type:"relation end", value: "aggregation", directional: false}}
RelationshipRightEnd
= RightExtendsToken {return {type:"relation end", value: "right extend", directional: true}}
/ RightArrowToken {return {type:"relation end", value: "right arrow", directional: true}}
/ CompositionToken {return {type:"relation end", value: "composition", directional: false}}
/ AggregationToken {return {type:"relation end", value: "aggregation", directional: false}}
RelationExpression
= left:RelationshipLeftEnd? body:RelationshipBody+ right:RelationshipRightEnd? {
return {
leftTerminal: left,
rightTerminal: right,
len: body.lenght
};
}
/* ----- A.4 Statements ----- */
Statments
= ElementRelationship
ElementRelationship
= lhs:Identifier __? rel:RelationExpression __? rhs:Identifier __ {
return {
leftHandElement: lhs,
rightHandElement: rhs,
relationship: rel
};
}
/* ----- A.5 UMLElements ----- */
StereotypeSpotDeclartion
= "(" id:IdentifierPart "," color:(HexIntegerLiteral/id:Identifier) ")" {
return {
shorthand:id,
color: color
};
}
StereotypeDeclaration
= StereotypeOpenToken spot:(StereotypeSpotDeclartion __)? id:Identifier StereotypeCloseToken {
return {
type:"stereotype",
name:id,
spot: extractOptional(spot, 0)||undefined
};
}
ClassDeclaration
= ClassToken __ id:Identifier __ stereoType:(StereotypeDeclaration __)? body:("{" __ ClassMembers* __ "}" __)? {
return {
umlobjtype: "class",
id: id,
body: optionalList(extractOptional(body, 2)),
stereotype: extractOptional(stereoType, 0)
};
}
ClassMembers
= __ scope:(ScopeModifier)? id:Identifier __
":" __ dtype:Identifier __ {
return {
type:"class member",
name: id,
data_type: dtype,
scope: scope||undefined
};
}
EnumDeclaration
= EnumToken __ id:Identifier __ body:("{" __ EnumMembers* __ "}" __)? {
return {
umlobjtype: "enum",
id: id,
body: optionalList(extractOptional(body, 2)),
};
}
EnumMembers
= id:Identifier __ {
return {
type:"enum member",
name: id
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment