这是一个带有几个约束的简单方法。我认为这些符合您在评论中提到的预期行为。
- 不匹配的
LPARAM
永远不会出现在子列表中
- 不匹配的
RPARAM
永远不会出现在子列表中
语法:
start : root+ EOF -> ^(LIST root+ );
root : expr
| LPARAM
| RPARAM
;
expr : list
| atom
;
list : LPARAM expr+ RPARAM -> ^(LIST expr+)
;
atom : INT
;
规则root
匹配不匹配LPARAM
的 s 和RPARAM
s。规则list
,atom
只关心自己。
该解决方案相对脆弱,因为 ruleroot
需要在和expr
之前列出。即便如此,也许这足以解决您的问题。LPARAM
RPARAM
测试用例 1:没有列表
输入:1 2 3
输出:
测试用例 2:一个列表
输入:1 (2) 3
输出:
测试用例 3:两个列表
输入:(1) 2 (3)
输出:
测试用例 4:没有列表,左不匹配
输入:((1 2 3
输出:
测试用例 5:两个列表,左不匹配
输入:((1 (2) (3)
输出:
测试用例 6:没有列表,权限不匹配
输入:1 2 3))
输出:
测试用例 7:两个列表,权限不匹配
输入:(1) (2) 3))
输出:
测试用例 8:两个列表,混合不匹配的左侧
输入:((1 (2) ( (3)
输出:
测试用例 9:两个列表,混合错配权限
输入:(1) ) (2) 3))
输出:
这是一个稍微复杂一点的语法,它作用于[]
和()
对。我认为当你添加对时,解决方案会变得更糟,但是,嘿,这很有趣!您可能还遇到了语法驱动的 AST 构建所能做的限制。
start : root+ EOF -> ^(LIST root+ )
;
root : expr
| LPARAM
| RPARAM
| LSQB
| RSQB
;
expr : plist
| slist
| atom
;
plist : LPARAM pexpr* RPARAM -> ^(LIST pexpr*)
;
pexpr : slist
| atom
| LSQB
| RSQB
;
slist : LSQB sexpr* RSQB -> ^(LIST sexpr*)
;
sexpr : plist
| atom
| LPARAM
| RPARAM
;
atom : INT;
INT : ('0'..'9')+;
LPARAM : '(';
RPARAM : ')';
LSQB : '[';
RSQB : ']';