ANTLR 语法获取一个句子作为单个标记
ANTLR Grammar to get a Sentence as Single Token
我正在尝试使用 ANTLR 语法解析 PlantUML 序列图。
我可以根据需要生成 AST。
但我面临的唯一问题是提取 activity 名称时。
PlantUML SequenceDiagram语法:
grammar SequenceDiagram;
uml:
'@startuml'
('autonumber')?
('hide footbox')?
(NEWLINE | sequence_diagram)
'@enduml'
;
sequence_diagram:
(node | relationship | NEWLINE)*
;
node:
('actor' | 'entity') ident 'as' ident;
relationship:
action
(NEWLINE* note)?
;
action:
left=ident
arrow
right=ident
':'
lable=ident
;
note:
'note' direction ':' ident
;
ident:
IDENT;
label:
ident (ident)+ ~(NEWLINE);
direction:
('left'|'right');
arrow:
('->'|'-->'|'<-'|'<--');
IDENT : NONDIGIT ( DIGIT | NONDIGIT )*;
NEWLINE : [\r\n]+ -> skip ;
COMMENT :
('/' '/' .*? '\n' | '/*' .*? '*/') -> channel(HIDDEN)
;
WS : [ ]+ -> skip ; // toss out whitespace
fragment NONDIGIT : [_a-zA-Z];
fragment DIGIT : [0-9];
fragment UNSIGNED_INTEGER : DIGIT+;
示例序列图代码:
@startuml
actor Alice as al
entity Bob as b
Alice -> Bob: Authentication_Request
Bob --> Alice: Authentication_Response
Alice -> Bob: Another_Authentication_Request
Alice <-- Bob: Another_Authentication_Response
note right: example_note
@enduml
生成的 AST:
请注意标签 -
Authentication_Request、Authentication_Response 等是一个单词(我的解决方法)。
我想将它们用作 space 分隔 - “身份验证请求”、“身份验证响应”等
我不知道如何将它们作为单个令牌获取。
如有任何帮助,我们将不胜感激。
编辑 1:
如何提取参与者和用例声明中的描述部分:
需要提取 Chef, "Food Critic", "Eat Food", ..., "Drink", ..., Test1
package Professional {
actor Chef as c
actor "Food Critic" as fc
}
package Restaurant {
usecase "Eat Food" as UC1
usecase "Pay for Food" as UC2
usecase "Drink" as UC3
usecase "Review" as UC4
usecase Test1
}
SOLUTION for the above edit:
node:
('actor' | 'usecase') (ident | description) 'as'? ident?;
description:
DESCRIPTION;
DESCRIPTION: '"' ~["]* '"';
也许使用“:”和 EOL 作为分隔符。 (看PlantUML网站,好像是这么用的(至少序列图是这样的)
您需要删除 action
规则的 ’:‘
部分(并在使用您的 LABELS 令牌时去除前导 :
)。您可以使用 Lexer 模式避免这种情况,但这似乎有点过分了。
plantUML 站点包含此示例:
@startuml
Alice -> Alice: This is a signal to self.\nIt also demonstrates\nmultiline \ntext
@enduml
因此,您需要非常灵活地接受 LABEL
令牌中的内容。 (它不仅仅是一个或多个 IDENT
s),所以我使用的规则只选取从“:”到 EOL 的所有内容。
action:
left=ident
arrow
right=ident
LABEL
;
LABEL: ‘:’ ~[\r\n]*;
我正在尝试使用 ANTLR 语法解析 PlantUML 序列图。
我可以根据需要生成 AST。
但我面临的唯一问题是提取 activity 名称时。
PlantUML SequenceDiagram语法:
grammar SequenceDiagram;
uml:
'@startuml'
('autonumber')?
('hide footbox')?
(NEWLINE | sequence_diagram)
'@enduml'
;
sequence_diagram:
(node | relationship | NEWLINE)*
;
node:
('actor' | 'entity') ident 'as' ident;
relationship:
action
(NEWLINE* note)?
;
action:
left=ident
arrow
right=ident
':'
lable=ident
;
note:
'note' direction ':' ident
;
ident:
IDENT;
label:
ident (ident)+ ~(NEWLINE);
direction:
('left'|'right');
arrow:
('->'|'-->'|'<-'|'<--');
IDENT : NONDIGIT ( DIGIT | NONDIGIT )*;
NEWLINE : [\r\n]+ -> skip ;
COMMENT :
('/' '/' .*? '\n' | '/*' .*? '*/') -> channel(HIDDEN)
;
WS : [ ]+ -> skip ; // toss out whitespace
fragment NONDIGIT : [_a-zA-Z];
fragment DIGIT : [0-9];
fragment UNSIGNED_INTEGER : DIGIT+;
示例序列图代码:
@startuml
actor Alice as al
entity Bob as b
Alice -> Bob: Authentication_Request
Bob --> Alice: Authentication_Response
Alice -> Bob: Another_Authentication_Request
Alice <-- Bob: Another_Authentication_Response
note right: example_note
@enduml
生成的 AST:
请注意标签 -
Authentication_Request、Authentication_Response 等是一个单词(我的解决方法)。
我想将它们用作 space 分隔 - “身份验证请求”、“身份验证响应”等
我不知道如何将它们作为单个令牌获取。
如有任何帮助,我们将不胜感激。
编辑 1:
如何提取参与者和用例声明中的描述部分: 需要提取 Chef, "Food Critic", "Eat Food", ..., "Drink", ..., Test1
package Professional {
actor Chef as c
actor "Food Critic" as fc
}
package Restaurant {
usecase "Eat Food" as UC1
usecase "Pay for Food" as UC2
usecase "Drink" as UC3
usecase "Review" as UC4
usecase Test1
}
SOLUTION for the above edit:
node:
('actor' | 'usecase') (ident | description) 'as'? ident?;
description:
DESCRIPTION;
DESCRIPTION: '"' ~["]* '"';
也许使用“:”和 EOL 作为分隔符。 (看PlantUML网站,好像是这么用的(至少序列图是这样的)
您需要删除 action
规则的 ’:‘
部分(并在使用您的 LABELS 令牌时去除前导 :
)。您可以使用 Lexer 模式避免这种情况,但这似乎有点过分了。
plantUML 站点包含此示例:
@startuml
Alice -> Alice: This is a signal to self.\nIt also demonstrates\nmultiline \ntext
@enduml
因此,您需要非常灵活地接受 LABEL
令牌中的内容。 (它不仅仅是一个或多个 IDENT
s),所以我使用的规则只选取从“:”到 EOL 的所有内容。
action:
left=ident
arrow
right=ident
LABEL
;
LABEL: ‘:’ ~[\r\n]*;