Skip to content

Angex 语法规范(钓法表达式)

本文由 AI 生成

本文档以 AngexParser 的实际实现为准,是 Angex 的权威语法规范,面向高级用户与开发者。 本文明确不包含正则解析器的语法。

下文描述的是当前解析器能够接受的语法。如需扩展语法,请先修改此规范,再修改解析器。

记号说明

  • 采用 EBNF 风格。
  • WS 表示可选空白;解析器在多数位置会跳过空白。
  • 终结符用字面量表示,如 "平钓"">"
  • 某些规则由解析器自定义逻辑实现,以下以文字说明。

词法 / 符号

空白

  • 空白可出现在大多数标记之间,解析器会跳过它们。
  • 括号内容中的空白会保留,并在列表项级别进行 Trim

等价符号

  • 阶段分隔符:>
  • 游动饵标记:<
  • 段分隔符:;
  • 咬饵标记:!
  • 括号对:[]【】(), ( )
  • 天气括号仅允许 ()( )

列表分隔符

  • 目标/天气列表分隔符:||
  • 修饰词列表分隔符:||
  • 注意:单个 | 保留给 name|idIdOrName 语法。

排除前缀

  • 支持全角 与半角 ?

备注

  • // 开始备注,直到文本结尾。

关键字

模式

平钓 | 大鱼 | 耐心 | nm | bf | pt

咬饵类型

全部 | all | ! | !! | !!!! 数量为 1-3)

提钩类型

强力 | 精准 | 双重 | 双提 | 三重 | 三提 | 华丽 | pw | pc | dh | th | sh

阶段 1 的内联特殊

拍水 | 拍 | ss | 专一 | 专 | ic

嵌套关键字

阶段 | stg | stage | 鱼识 | int | 拍水后 | pss | 专一后 | pic | 拍水 | 拍 | ss | 专一 | 专 | ic

修饰词(全局参数)

不撒饵/nochum, 收藏品/coll, 不收集/nocoll, 钓组/snag, 大尺寸/large, 攒鱼计/aa, 套娃/mooch-loop, 梭哈/all-in, 等待专一/waitic, 大鱼知识/bfg, 引诱/lure, 雄心/a-lure, 谦逊/m-lure, 重随/re-roll, 鱼影/shadow, 多提/mhs, 加钩/mh, 回收/recy, 鱼眼/fe, 鱼篓/sh, 鱼篓专一/sh-ic, 多提回退/mhs-back, 允许溢出/overflow, 等待华丽/wait-sh, 跳阶段/skipstg, 强制预备/force-prep, 银星/silver, 无强心剂/nocord, 无恩宠/nofavor

补充:引诱/雄心/谦逊/鱼影/重随 可在末尾追加正整数以限制引诱叠层上限(按当前身上引诱 buff 层数判断),例如 引诱2a-lure3。当存在 鱼影重随 修饰词时,该限制不生效。

语法(EBNF)

ebnf
Expression     ::= WS* Mode WS* BaitOpt WS* WindowOpt WS* Arrow WS* Phase1
                   (WS* Arrow WS* Phase)* WS* GlobalParamsOpt WS* NestedExprsOpt WS* RemarkOpt WS* ;

Mode           ::= "平钓" | "大鱼" | "耐心" | "nm" | "bf" | "pt" ;
Arrow          ::= ">" | "》" ;

BaitOpt        ::= BracketedId | ε ;
BracketedId    ::= Brackets IdOrName ;
Brackets       ::= "[" "]" | "【" "】" | "(" ")" | "(" ")" ;

WindowOpt      ::= "@" WS* EtRangeOpt WS* WeatherOpt | ε ;
EtRangeOpt     ::= EtRange | ε ;
EtRange        ::= EtTime WS* ("-" | "~") WS* EtTime ;
EtTime         ::= Digit Digit Digit Digit ;
WeatherOpt     ::= WeatherBracket | ε ;
WindowArrow    ::= "=" WS* Arrow ;
WeatherBracket ::= ("(" | "(") WeatherInner (")" | ")") ;
WeatherInner   ::= WeatherList (WS* WindowArrow WS* WeatherList)? ;
WeatherList    ::= IdOrName (WS* ListSep WS* IdOrName)* ;

Phase1         ::= Phase InlineSpecialsOpt ;
Phase          ::= ExtraBiteOpt WS* BiteTimeOpt WS* BiteTypes WS* HooksetOpt
                   WS* SwimbaitOpt WS* TargetsOpt ;

ExtraBiteOpt   ::= ("(" | "(") ExtraBiteToken (")" | ")") | ε ;

BiteTimeOpt    ::= BiteTimeRange | ε ;
BiteTimeRange  ::= RangeStartMax | RangeMin RangeMaxReq ;
RangeStartMax  ::= ("-" | "~") Number ("+" Number)? ;
RangeMin       ::= Number ("+" Number)? ;
RangeMaxReq    ::= RangeMax | RangeOpenEnd ;
RangeMax       ::= ("-" | "~") Number ("+" Number)? ;
RangeOpenEnd   ::= ("-" | "~") ;
Number         ::= Digit+ ("." Digit+)? ;

BiteTypes      ::= AllBite | BangToken (WS* "+" WS* BangToken)* ;
AllBite        ::= "全部" | "all" ;
BangToken      ::= ("!" | "!"){1,3} ;
Bang1to3       ::= ("!" | "!"){1,3} ;
ExtraBiteToken ::= AllBite | Bang1to3 ;

HooksetOpt     ::= Hookset Digit? | ε ;
Hookset        ::= "强力" | "精准" | "双重" | "双提" | "三重" | "三提" | "华丽"
                 | "pw" | "pc" | "dh" | "th" | "sh" ;

InlineSpecialsOpt ::= (WS* "@" WS* InlineSpecial)+ | ε ;
InlineSpecial     ::= InlineSlap | InlineExclusive ;
InlineSlap         ::= ("拍水" | "ss")? WS* InlineSlapBody ;
InlineExclusive    ::= ("专一" | "ic") WS* InlineExclusiveBody ;
InlineSlapBody     ::= BiteTimeOpt WS* BiteTypesOpt WS* HooksetOpt WS* InlineTarget ;
BiteTypesOpt       ::= BiteTypes | ε ;
InlineExclusiveBody ::= TargetSet WS* HooksetOpt ;
InlineTarget       ::= SwimbaitTarget | TargetSet ;

SwimbaitOpt     ::= SwimbaitTarget | SwimbaitPlaceholder | ε ;
SwimbaitTarget  ::= ("<" | "《") WS* TargetSet ;
SwimbaitPlaceholder ::= ("<" | "《") ;
TargetsOpt      ::= TargetSet | ε ;

TargetSet       ::= Brackets TargetList ;
TargetList      ::= TargetToken (WS* ListSep WS* TargetToken)* ;
ListSep         ::= "、" | "||" ;
TargetToken     ::= ExclusionPrefix? TargetAtom ;
ExclusionPrefix ::= "?" | "?" ;
TargetAtom      ::= "any" | "任何" | "占位" | "ph" | "《" | IdOrName ;
IdOrName        ::= NAME ("|" UINT)? | UINT ;

GlobalParamsOpt ::= "=" WS* GlobalSeg (WS* SegmentSep WS* GlobalSeg)* WS* SegmentSep | ε ;
SegmentSep      ::= ";" | ";" ;
GlobalSeg       ::= CounterOrTerm | ModifierList ;
CounterOrTerm   ::= UINT? WS* TargetSet ;
ModifierList    ::= ModifierToken (WS* ModifierSep WS* ModifierToken)* ;
ModifierSep     ::= "、" | "||" ;
ModifierToken   ::= <见上文修饰词列表> ;

NestedExprsOpt  ::= (WS* NestedExpr)* | ε ;
NestedExpr      ::= "@" WS* NestedKind WS* "=" WS* Arrow WS* Expression StageCloseOpt ;
NestedKind      ::= "阶段" | "stg" | "stage"
                  | "鱼识" | "int"
                  | "拍水后" | "pss"
                  | "专一后" | "pic"
                  | "拍水" | "ss"
                  | "专一" | "ic" ;
StageCloseOpt   ::= (WS* ("<" | "《") WS* "=") | ε ;

RemarkOpt       ::= "//" RemarkText | ε ;
RemarkText      ::= <任意字符直到结尾> ;

WS              ::= <空白> ;
Digit           ::= "0".."9" ;
UINT            ::= Digit+ ;
NAME            ::= <不包含列表分隔符的非空文本> ;

补充:RangeMin 后仅出现 -~ 表示“以上”(无上限)。

语义约束与解析说明

  1. 窗口期 (@) 至少包含以下之一:

    • ET 时间段,或
    • 天气集合。 否则报错“窗口期为空”。
    • 双段天气必须写在同一组括号内,例如 (晴朗=>阴云)(晴朗=》阴云)
  2. ET 时间为 4 位数字(0000-2359),2400 被视为 0000

  3. 咬饵类型:

    • 每个阶段必须存在。
    • 全部/all 不能与 ! 混用。
  4. 咬饵时间:

    • 仅提供一组数值时,必须显式包含 -~(前置或后置)。
  5. 阶段目标:

    • 游动饵目标与普通目标不可同时存在。
  6. 额外咬饵类型:

    • 支持 全部/all 或 1-3 个 !
    • 若无效,解析会回退并在后续以“缺少咬饵类型”等错误结束。
  7. 提钩类型:

    • 如果给出多重提钩数量,则必须给出提钩类型。
  8. 内联特殊(仅阶段 1):

    • 内联拍水必须有目标(<[...][...])。
    • 内联专一必须有目标([...])。
    • 若内联拍水未给咬饵类型,则使用阶段 1 的咬饵类型与咬饵时间。
    • 允许出现在阶段 1 目标之前或之后(用于兼容旧写法与序列化输出)。
    • 序列化输出时会固定放在阶段 1 目标之前。
  9. 嵌套表达式:

    • 只能出现在全局参数之后。
    • @阶段=》... 必须闭合 < =《 =
    • @鱼识=》... 会尽可能吞掉其后的内容,直到备注开始(//)。
    • 其他嵌套关键字会消费到下一个嵌套表达式起始或备注起始(允许连续书写多个嵌套表达式)。
    • 若存在全局参数,嵌套表达式前必须以分号结束全局参数段。
  10. 鱼识 / 拍水后 / 专一后(同级互斥):

  • 同一层级最多出现一个(@鱼识 / @拍水后 / @专一后),否则报错。
  • 不同层级互不影响(例如外层 @鱼识,内层 @专一后 允许)。
  1. 全局参数:
  • = 开始全局参数。
  • ; 分隔多个段。
  • 全局参数最后一段必须以 ; 结束(即使后面是嵌套表达式或备注)。
  • 没有数量的目标段若位于第一个位置,则视为“终止目标”。
  • 计数器必须有数量。
  • 修饰词使用 || 连接,解析器允许仅修饰词而无目标段。
  • 引诱相关修饰词尾随数字表示“引诱最多叠到 X 层”,但在 鱼影重随 手法下会被忽略。
  1. 目标项:
  • any / 任何 表示“匹配任何”。
  • 占位 / ph 表示“不匹配任何”。
  • 作为目标项表示鱼篓标记。
  • / ? 前缀表示排除模式。
  1. 天气项:
  • 仅支持 IdOrName,不支持排除或占位等特殊项。
  1. 游动饵占位:
  • 单独出现的游动饵操作符(如 《》 中的 )会被视为“鱼篓标志”,等价于游动饵目标包含

最小示例

angex
平钓全部
nm > all

耐心青花鱼块|36593@1355-1600晴朗|26.1+10.3~!!!占位

Powered by VitePress