JS 实现UML序列图(二)——csdn MarkDown 第七篇 技术篇

上一篇大概说了一下JS是怎么画UML 图形的。
这一篇简单介绍一下这个JS 解析 UML语法是怎么实现的。
https://github.com/bramp/js-sequence-diagrams/blob/master/src/grammar.ebnf
这个是Markdown UML语言的语法结构。摘抄了部分:
这一部分是将词和词组成语句。而语句和语句就组成篇章。

1
2
3
4
5
6
7
document ::= statement*
statement ::=
( 'title' ':' message
| 'participant' actor
| 'note' ('left of' | 'right of' | 'over') actor ':' message
| actor ( '-' | '--' ) ( '>' | '>>' )? actor ':' message
)

这里的意思是 UML是由 statement(语句)构成的。
statement有下面几种表示方法:
1. ‘title’ ‘:’ message 这里带上’’的都是token,在编译原理中,token标识不能再被解释的词。
2. ‘participant’ actor
3. ‘note’ (‘left of’ | ‘right of’ | ‘over’) actor ‘:’ message 表示note与Actor之间的关系
4. actor ( ‘-’ | ‘–’ ) ( ‘>’ | ‘>>’ )? actor ‘:’ message 标识actor之间的关系。

下面的词法分析会将字符转换为UML中有含义的字。类似字符组成词。用正则式将字母变成有含义的词。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/** js sequence diagrams
* http://bramp.github.io/js-sequence-diagrams/
* (c) 2012-2013 Andrew Brampton (bramp.net)
* Simplified BSD license.
*/
%lex
%options case-insensitive
%{
// Pre-lexer code can go here
%}
%%
[\n]+ return 'NL';
\s+ /* skip whitespace */
\#[^\n]* /* skip comments */
"participant" return 'participant';
"left of" return 'left_of';
"right of" return 'right_of';
"over" return 'over';
"note" return 'note';
"title" return 'title';
"," return ',';
[^\->:\n,]+ return 'ACTOR';
"--" return 'DOTLINE';
"-" return 'LINE';
">>" return 'OPENARROW';
">" return 'ARROW';
:[^#\n]+ return 'MESSAGE';
<<EOF>> return 'EOF';
. return 'INVALID';
/lex
%start start
%% /* language grammar */
start
: document 'EOF' { return yy; }
;
document
: /* empty */
| document line
;
line
: statement { }
| 'NL'
;
statement
: 'participant' actor { $2; }
| signal { yy.addSignal($1); }
| note_statement { yy.addSignal($1); }
| 'title' message { yy.setTitle($2); }
;
note_statement
: 'note' placement actor message { $$ = new Diagram.Note($3, $2, $4); }
| 'note' 'over' actor_pair message { $$ = new Diagram.Note($3, Diagram.PLACEMENT.OVER, $4); }
;
actor_pair
: actor { $$ = $1; }
| actor ',' actor { $$ = [$1, $3]; }
;
placement
: 'left_of' { $$ = Diagram.PLACEMENT.LEFTOF; }
| 'right_of' { $$ = Diagram.PLACEMENT.RIGHTOF; }
;
signal
: actor signaltype actor message
{ $$ = new Diagram.Signal($1, $2, $3, $4); }
;
actor
: ACTOR { $$ = yy.getActor($1); }
;
signaltype
: linetype arrowtype { $$ = $1 | ($2 << 2); }
| linetype { $$ = $1; }
;
linetype
: LINE { $$ = Diagram.LINETYPE.SOLID; }
| DOTLINE { $$ = Diagram.LINETYPE.DOTTED; }
;
arrowtype
: ARROW { $$ = Diagram.ARROWTYPE.FILLED; }
| OPENARROW { $$ = Diagram.ARROWTYPE.OPEN; }
;
message
: MESSAGE { $$ = $1.substring(1).trim().replace(/\\n/gm, "\n"); }
;
%%

例如下面这一句:

1
[^\->:\n,]+ return 'ACTOR';

就是将不是’->:\n,’这些字符的多个字组成词,这个词叫做ACTOR.

一般来说终结符也就是类似’note’ 这样的字符需要先被定义。否则 ‘note’这样的字符集合就变成了markdown UML的ACTOR.

而下面的是将ACTOR词转成对象actor。

1
2
3
actor
: ACTOR { $$ = yy.getActor($1); }
;

好吧上面就是UML的grammar. 其实用什么语言都可以写出来。不局限于JS. 具体grammar这块使用的是jison和ebnf.
有闲空的人可以看一下JS调用jison来做js parser以及EBNF表达式。

  • 本文作者: 帐前卒
  • 本文链接: http://chillyc.info/2015/44654639/
  • 版权声明: 本博客所有文章除特别声明外,只能复制超链接地址,且必须注明出处!