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 令牌中的内容。 (它不仅仅是一个或多个 IDENTs),所以我使用的规则只选取从“:”到 EOL 的所有内容。

action:
    left=ident 
    arrow 
    right=ident 
    LABEL
    ;

LABEL: ‘:’ ~[\r\n]*;