用于 PlantUML 的带有 XText 的 DSL
DSL with XText for PlantUML
目前我正在尝试为 PlantUML 的 class 图创建 DSL。我是 Xtext 的新手,我无法理解几件事。在列出我的问题之前,我会向您展示我当前语法的某些部分:
ClassUml:
{ClassUml}
'@startuml' umlElements+=(ClassElement)* '@enduml';
ClassElement:
Class
| Association;
Class:
{Class}
'class' name=ClassName
(color=ColorTag)?
('{' (classContents+=ClassContent)* '}')?;
ClassContent:
Attribute | Method;
ClassName:
(ID | STRING);
Attribute:
{Attribute}
(visibility=Visibility)? name=ID (":" type=ID)?;
Method:
{Method}
(visibility=Visibility)? name=METHID
(":" type=ID)?;
Association:
{Association}
(classFrom=[Class]
associationType=Bidirectional
classTo=[Class])
|
(classTo=[Class]
associationType=UnidirectionalLeft
classFrom=[Class])
|
(classFrom=[Class]
associationType=UnidirectionalRight
classTo=[Class])
(':' text+=(ID)*)?;
Bidirectional:
{Bidrectional}
('-' ("[" color=ColorTag "]")? '-'?)
| ('.' ("[" color=ColorTag "]")? '.'?);
UnidirectionalLeft:
{UnidirectionalLeft}
('<-' ("[" color=ColorTag "]")? '-'?)
| ('<.' ("[" color=ColorTag "]")? '.'?);
UnidirectionalRight:
{UnidirectionalRight}
((('-[' color=ColorTag "]")|'-')? '->')
| ((('.[' color=ColorTag "]")|'.')? '.>');
ColorTag:
(COLOR | HEXCODE);
enum Visibility:
PROTECTED='#'
| PRIVATE='-'
| DEFAULT='~'
| PUBLIC='+';
terminal COLOR:
"#"
('red') | ('orange');
terminal HEXCODE:
"#"
('A' .. 'F'|'0' .. '9')('A' .. 'F'|'0' .. '9')('A' .. 'F'|'0' .. '9')
('A' .. 'F'|'0' .. '9')('A' .. 'F'|'0' .. '9')('A' .. 'F'|'0' .. '9');
terminal STRING:
'"' ('\' . | !('\' | '"'))* '"';
terminal ID:
('a'..'z' | 'A'..'Z' | '_' | '0'..'9' | '\"\"' | '//' | '\')
('a'..'z' | 'A'..'Z' | '_' | '0'..'9' | '\"\"' | '//' | '\' | ':')*;
我省略了其他关联类型(--*、--o、--|>),因为我用相同的方式定义了它们。
问题
1. 如果不与方法/属性名称分开,可见性枚举“#”将无法工作。但所有其他情况 (+,-,~) 都很好,中间有和没有空格 space.
2. 联想在大多数情况下似乎不起作用。我列出了几个例子:
' Working '
Alice -* Bob : Hello
Alice - Bob
Alice .o Bob
Alice <|-[#002211]- Bob
Alice *-[#red]- Bob
Alice -[#000000]-> Bob
Alice .[#red].> Bob
' Not Working '
Alice *-- Bob
Alice --* Bob
Alice .. Bob
Alice -[#ff0022]- Bob
Alice <-- Bob
Alice ..> Bob
Alice -- Bob
- 我不知道如何使用由 STRING 而不是 ID 定义的 classes 的交叉引用。
另外我猜想方法名称的附加终端是一个奇怪的解决方案,应该以不同的方式处理。
1) 颜色应该是解析器规则而不是终端规则。
同时删除 Hex 规则并简单地使用您更改的 ID 规则。
Color:
"#" ('red' | 'orange' | ID);
2) 一定要统一区别,比如
之间有冲突
Bidirectional:
...
('-' ("[" ...;
和
UnidirectionalRight:
((('-[' ...;
序列 '-[' 将始终匹配后一个版本。您应该创建一个规则 AssociationType 并使其适用于所有情况。像这样:
Association:
{Association}
(classFrom=[Class | ClassName]
associationType=AssociationType
classTo=[Class | ClassName])
(':' text+=(ID)*)?;
AssociationType:
{AssociationType}
left?='<'? ('-'|'.') ("[" color=Color "]")? ('-'|'.') right?='>'?;
3) 您也可以在交叉引用中使用 STRING,方法是对交叉引用使用以下语法:classFrom=[Class|ClassName]
目前我正在尝试为 PlantUML 的 class 图创建 DSL。我是 Xtext 的新手,我无法理解几件事。在列出我的问题之前,我会向您展示我当前语法的某些部分:
ClassUml:
{ClassUml}
'@startuml' umlElements+=(ClassElement)* '@enduml';
ClassElement:
Class
| Association;
Class:
{Class}
'class' name=ClassName
(color=ColorTag)?
('{' (classContents+=ClassContent)* '}')?;
ClassContent:
Attribute | Method;
ClassName:
(ID | STRING);
Attribute:
{Attribute}
(visibility=Visibility)? name=ID (":" type=ID)?;
Method:
{Method}
(visibility=Visibility)? name=METHID
(":" type=ID)?;
Association:
{Association}
(classFrom=[Class]
associationType=Bidirectional
classTo=[Class])
|
(classTo=[Class]
associationType=UnidirectionalLeft
classFrom=[Class])
|
(classFrom=[Class]
associationType=UnidirectionalRight
classTo=[Class])
(':' text+=(ID)*)?;
Bidirectional:
{Bidrectional}
('-' ("[" color=ColorTag "]")? '-'?)
| ('.' ("[" color=ColorTag "]")? '.'?);
UnidirectionalLeft:
{UnidirectionalLeft}
('<-' ("[" color=ColorTag "]")? '-'?)
| ('<.' ("[" color=ColorTag "]")? '.'?);
UnidirectionalRight:
{UnidirectionalRight}
((('-[' color=ColorTag "]")|'-')? '->')
| ((('.[' color=ColorTag "]")|'.')? '.>');
ColorTag:
(COLOR | HEXCODE);
enum Visibility:
PROTECTED='#'
| PRIVATE='-'
| DEFAULT='~'
| PUBLIC='+';
terminal COLOR:
"#"
('red') | ('orange');
terminal HEXCODE:
"#"
('A' .. 'F'|'0' .. '9')('A' .. 'F'|'0' .. '9')('A' .. 'F'|'0' .. '9')
('A' .. 'F'|'0' .. '9')('A' .. 'F'|'0' .. '9')('A' .. 'F'|'0' .. '9');
terminal STRING:
'"' ('\' . | !('\' | '"'))* '"';
terminal ID:
('a'..'z' | 'A'..'Z' | '_' | '0'..'9' | '\"\"' | '//' | '\')
('a'..'z' | 'A'..'Z' | '_' | '0'..'9' | '\"\"' | '//' | '\' | ':')*;
我省略了其他关联类型(--*、--o、--|>),因为我用相同的方式定义了它们。
问题
1. 如果不与方法/属性名称分开,可见性枚举“#”将无法工作。但所有其他情况 (+,-,~) 都很好,中间有和没有空格 space.
2. 联想在大多数情况下似乎不起作用。我列出了几个例子:
' Working '
Alice -* Bob : Hello
Alice - Bob
Alice .o Bob
Alice <|-[#002211]- Bob
Alice *-[#red]- Bob
Alice -[#000000]-> Bob
Alice .[#red].> Bob
' Not Working '
Alice *-- Bob
Alice --* Bob
Alice .. Bob
Alice -[#ff0022]- Bob
Alice <-- Bob
Alice ..> Bob
Alice -- Bob
- 我不知道如何使用由 STRING 而不是 ID 定义的 classes 的交叉引用。
另外我猜想方法名称的附加终端是一个奇怪的解决方案,应该以不同的方式处理。
1) 颜色应该是解析器规则而不是终端规则。 同时删除 Hex 规则并简单地使用您更改的 ID 规则。
Color:
"#" ('red' | 'orange' | ID);
2) 一定要统一区别,比如
之间有冲突Bidirectional:
...
('-' ("[" ...;
和
UnidirectionalRight:
((('-[' ...;
序列 '-[' 将始终匹配后一个版本。您应该创建一个规则 AssociationType 并使其适用于所有情况。像这样:
Association:
{Association}
(classFrom=[Class | ClassName]
associationType=AssociationType
classTo=[Class | ClassName])
(':' text+=(ID)*)?;
AssociationType:
{AssociationType}
left?='<'? ('-'|'.') ("[" color=Color "]")? ('-'|'.') right?='>'?;
3) 您也可以在交叉引用中使用 STRING,方法是对交叉引用使用以下语法:classFrom=[Class|ClassName]