You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Python Lark EBNF以正确解析PlantUML条件分支内语句?

问题描述

我需要用Python的Lark包解析类流程图的PlantUML代码,其中每个action的语法基于Verilog-HDL。现有PlantUML包含条件分支,使用给定的EBNF解析时,if分支外的语句可正常解析,但分支内的同名语句报错(提示当前上下文不匹配':')。我需要将write(reg01, 8'h01, )提取为单个expression token,请问该如何修改EBNF?


PlantUML代码

@startuml
:[7:0] a;
:write(reg01, 8'h01, );

if (flag == 1'b1) then (Yes)
  :write(reg01, 8'h01, );
endif
@enduml

原EBNF规则

start: "@startuml" (statement | cond_if)* "@enduml"

cond_if: "if" "(" condition ")" "then" "(" "Yes" ")" (statement)* "endif"

statement: ":" expression ";"
condition: expression
expression: /[^;\n]+/

%import common.WS
%ignore WS

错误信息

Error: No terminal matches ':' in the current parser context, at line 6 col 3

  :write(reg01, 8'h01, );
  ^
Expected one of:
        * RPAR

问题原因与修改方案

问题根源

原EBNF中expression: /[^;\n]+/是贪婪匹配规则,会匹配除分号、换行外的所有字符。在解析if (flag == 1'b1) then (Yes)时,condition对应的expression会把flag == 1'b1) then (Yes全部匹配,导致解析器认为if的条件括号尚未闭合,因此遇到分支内的:时,会错误地预期右括号RPAR,从而触发报错。

修改后的EBNF

针对这个问题,我们需要给condition单独定义更精确的匹配规则,避免它匹配到条件括号之外的内容。以下是两种可行的修改方案:

方案1:适配无嵌套括号的条件(简单场景)

如果你的条件表达式不会出现嵌套括号,可以直接限制condition只匹配到第一个右括号之前的内容:

start: "@startuml" (statement | cond_if)* "@enduml"

cond_if: "if" "(" condition ")" "then" "(" "Yes" ")" (statement)* "endif"

statement: ":" expression ";"
# 仅匹配条件括号内的内容,直到第一个右括号
condition: /[^)]+/
# 语句表达式保留原有规则,匹配到分号/换行前的所有内容(含括号)
expression: /[^;\n]+/

%import common.WS
%ignore WS

方案2:支持嵌套括号的条件(通用场景)

如果条件表达式可能包含嵌套括号,可以用递归规则处理括号结构,确保解析器能正确识别括号的闭合:

start: "@startuml" (statement | cond_if)* "@enduml"

cond_if: "if" "(" condition ")" "then" "(" "Yes" ")" (statement)* "endif"

statement: ":" stmt_expr ";"
condition: cond_expr

# 语句表达式:允许文本和嵌套括号组
stmt_expr: (TEXT | PAREN_GROUP)+
# 条件表达式:同语句表达式规则,支持嵌套括号
cond_expr: (TEXT | PAREN_GROUP)+

# 定义括号组:匹配括号及内部的所有内容(支持嵌套)
PAREN_GROUP: "(" (TEXT | PAREN_GROUP | WS)* ")"
# 定义文本:匹配除括号、分号、换行外的所有字符
TEXT: /[^();\n]+/

%import common.WS
%ignore WS

修改效果

修改后,解析器能正确识别if语句的完整结构,分支内的statement会被正常解析,write(reg01, 8'h01, )也会被提取为单个expression token。


内容的提问来源于stack exchange,提问作者Asustor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 06:04:53