我试图弄清楚为什么我的Antlr生成的解析器无法将输入的一部分识别为与我的一条规则(“ and_converge”规则,“网关”的一部分)匹配。我的语法如下:
process : PROCESS id CURLY_OPEN (stmt_list | pool_list) CURLY_CLOSE EOF ; /* starting rule */
stmt_list : (stmt STMT_TERM?)* ;
stmt : sequence | sequence_elem | association ;
sequence : sequence_elem sequence_flow sequence_elem (sequence_flow sequence_elem)* ;
sequence_elem : activity | gateway | event | link ;
activity : task | subprocess ;
task : SQRE_OPEN task_type id
(VERT_LINE (input_set)? (output_set)?)? /* input/output sets */
(VERT_LINE attr_list)? /* attributes for activity */
(VERT_LINE boundary_event)* /* associated boundary events */
SQRE_CLOSE ;
task_type : USER | SERVICE | SCRIPT ;
event : PAREN_OPEN event_type id (VERT_LINE attr_list)? PAREN_CLOSE ;
gateway : ANGLE_OPEN (fork_diverge | condition_diverge | event_diverge | and_converge | or_converge) ANGLE_CLOSE ;
fork_diverge : FORK id (VERT_LINE attr_list)? VERT_LINE outflows ;
event_diverge : EVENT_SPLIT VERT_LINE event_links ;
condition_diverge : (OR_SPLIT | XOR_SPLIT) id (VERT_LINE attr_list)? VERT_LINE cond_outflows ;
and_converge : JOIN id (VERT_LINE attr_list)? (VERT_LINE inflows)? ;
or_converge : (XOR_JOIN | OR_JOIN) id (VERT_LINE attr_list)? (VERT_LINE inflows)? ;
inflows : IN ':' link_list ;
outflows : OUT ':' link_list ;
cond_outflows : OUT ':' cond_outflow (',' cond_outflow)* (DEFAULT ':' link)?;
cond_outflow : expression ':' link ;
为了简洁起见,我省略了大部分语法,但是您可以在此处看到完整版本:https://github.com/bspies/dotbpm/blob/dotbpm-parser/src/main/java/dot/bpm/parser/antlr/DOTBPM.g4。
当我在语法中输入以下内容时,它将失败:
/* A fork followed by a join, 4 "sequences" altogether */
process fork_join {
(> start) ==> [user t1] ==>
<fork g1 | out: #[t2], #[t3]>
[user t2] ==> #<g2>
[user t3] ==> #<g2>
<join g2> ==> (/ end)
}
它在与“加入”网关:line 7:4 no viable alternative at input '<join'
的行上失败。对其进行调试,似乎无法遵循“ stmt”规则,无法确定采用哪种替代方法。考虑到执行它的“ fork”规则工作得很好,并且在语法上(即通过“ gateway”规则)采用了非常相似的路径,因此这令人感到困惑。
解析树在这里:
答案 0 :(得分:1)
如果运行此代码:
String source = "/* A fork followed by a join, 4 \"sequences\" altogether */\n" +
"process fork_join {\n" +
" (> start) ==> [user t1] ==>\n" +
" <fork g1 | out: #[t2], #[t3]>\n" +
" [user t2] ==> #<g2>\n" +
" [user t3] ==> #<g2>\n" +
" <join g2> ==> (/ end)\n" +
"}";
DOTBPMLexer lexer = new DOTBPMLexer(CharStreams.fromString(source));
CommonTokenStream stream = new CommonTokenStream(lexer);
stream.fill();
for (Token t : stream.getTokens()) {
System.out.printf("type=%-20s text=`%s`%n", DOTBPMLexer.VOCABULARY.getDisplayName(t.getType()), t.getText().replace("\n", "\\n"));
}
并检查其输出:
type=PROCESS text=`process`
type=ID text=`fork_join`
type='{' text=`{`
type='(' text=`(`
type='>' text=`>`
type=ID text=`start`
type=')' text=`)`
type='==>' text=`==>`
type='[' text=`[`
type=USER text=`user`
type=ID text=`t1`
type=']' text=`]`
type='==>' text=`==>`
type='<' text=`<`
type=FORK text=`fork`
type=ID text=`g1`
type='|' text=`|`
type=OUT text=`out`
type=':' text=`:`
type='#' text=`#`
type='[' text=`[`
type=ID text=`t2`
type=']' text=`]`
type=',' text=`,`
type='#' text=`#`
type='[' text=`[`
type=ID text=`t3`
type=']' text=`]`
type='>' text=`>`
type='[' text=`[`
type=USER text=`user`
type=ID text=`t2`
type=']' text=`]`
type='==>' text=`==>`
type='#' text=`#`
type='<' text=`<`
type=ID text=`g2`
type='>' text=`>`
type='[' text=`[`
type=USER text=`user`
type=ID text=`t3`
type=']' text=`]`
type='==>' text=`==>`
type='#' text=`#`
type='<' text=`<`
type=ID text=`g2`
type='>' text=`>`
type='<' text=`<`
type=ID text=`join`
type=ID text=`g2`
type='>' text=`>`
type='==>' text=`==>`
type='(' text=`(`
type='/' text=`/`
type=ID text=`end`
type=')' text=`)`
type='}' text=`}`
type=EOF text=`<EOF>`
您会看到输入join
变成了ID
,而不是JOIN
。这就是Mike首先打印令牌的意思。
这是因为您有错字:
JOIN : [Jj}[Oo][Ii][Nn] ; /* synchronized merge (AND) */
OR_JOIN : [Oo][Rr]'-'[Jj}[Oo][Ii][Nn] ; /* structured synchronized merge (OR) */
XOR_JOIN : [Xx][Oo][Rr]'-'[Jj}[Oo][Ii][Nn] ; /* unsynchronized merge (XOR) */
请注意所有这些词法分析器规则中的[Jj}[Oo]
,它们将匹配一个字符(J
,j
,}
,[
中的一个,O
或o
)。
您(最有可能)的意思是:
JOIN : [Jj][Oo][Ii][Nn] ; /* synchronized merge (AND) */
OR_JOIN : [Oo][Rr]'-'[Jj][Oo][Ii][Nn] ; /* structured synchronized merge (OR) */
XOR_JOIN : [Xx][Oo][Rr]'-'[Jj][Oo][Ii][Nn] ; /* unsynchronized merge (XOR) */