ANTLR4 在输入 'do { return' 错误时没有可行的选择?
ANTLR4 no viable alternative at input 'do { return' error?
当我尝试解析输入时,此 ANTLR4 解析器语法错误 'no viable alternative'。我所知道的唯一匹配输入错误部分的规则是规则 'retblock_expr' 和 'block_expr'。我已将 'retblock_expr' 放在 'block_expr' 前面并将 'non_assign_expr' 放在 'retblock_expr' 前面,但它仍然会引发错误。
输入:
print(do { return a[3] })
完全错误:
line 1:11 no viable alternative at input '(do { return'
解析器语法:
parser grammar TestP;
options { tokenVocab=Test; }
program: ( ( block_expr | retblock_expr ) ( wsp ( block_expr | retblock_expr ) wsp )* wsp )? EOF;
retblock_expr
: isglobal DEF wsp fcreatable wsp fcall wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #FuncBlockA
| FUNC wsp fcall wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #CFuncBlockA
| LAMBDA wsp fcall wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #LambdaBlockA
| SWITCH wsp atompar_option wsp ( DO wsp )? ( LBC wsp (CASE wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )* ( DEFAULT wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )? wsp RBC | (CASE wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )* ( DEFAULT wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )? wsp END ) #SwitchBlockA
| DO wsp ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #DoBlockA
;
non_assign_expr
: ( iterable ( ( DOT | SUP | SIB ) iterable )+ | index ) #AccessExpr
| ( call | datat | LPR non_assign_expr RPR | LBC non_assign_expr RBC | LBR non_assign_expr RBR ) #BracketsExpr
| ( STR | KUN )+ indexable #UnpackExpr
| <assoc=right> non_assign_expr ( wsp POW wsp non_assign_expr )+ #PowExpr
| non_assign_expr ( wsp ( INC | DEC ) wsp non_assign_expr | INC | DEC )+ #CrementExpr
| ( PLS | MNS | BNT | EXC | LEN | NOT )+ non_assign_expr #UnaryExpr
| non_assign_expr EXC+ #FactExpr
| non_assign_expr ( wsp ( STR | DIV | PER | FDV | CDV ) wsp non_assign_expr | PER )+ # AdvExpr
| non_assign_expr ( wsp ( PLS | MNS ) wsp non_assign_expr )+ #BasicExpr
| non_assign_expr ( wsp CON wsp non_assign_expr )+ #ConcatExpr
| non_assign_expr ( wsp ( BLS | BRS ) wsp non_assign_expr )+ #ShiftExpr
| non_assign_expr ( wsp ( LET | LTE | GRT | GTE ) wsp non_assign_expr )+ #CompareExpr
| non_assign_expr ( wsp ( EQL | IS | NEQ | IS wsp NOT ) wsp non_assign_expr )+ #EqualExpr
| non_assign_expr ( wsp BND wsp non_assign_expr )+ #BitAnd
| non_assign_expr ( wsp BXR wsp non_assign_expr )+ #BitXor
| non_assign_expr ( wsp BOR wsp non_assign_expr )+ #BitOr
| <assoc=right> non_assign_expr ( wsp ( AND | TND ) wsp non_assign_expr wsp ( OR | TOR ) wsp non_assign_expr )+ #Ternary
| non_assign_expr ( wsp ( NND | AND ) wsp non_assign_expr )+ #AndExpr
| non_assign_expr ( wsp ( NXR | XOR ) wsp non_assign_expr )+ #XorExpr
| non_assign_expr ( wsp ( NOR | OR ) wsp non_assign_expr )+ #OrExpr
| retblock_expr #RBlockA
| typet LPR non_assign_expr RPR #TypeCastA
| atom #AtomNAE
;
block_expr
: IF wsp non_assign_expr wsp ( ( THEN wsp block_expr | LBC wsp block_expr wsp RBC ) wsp ( ( ELIF wsp non_assign_expr wsp THEN wsp block_expr | ELIF wsp non_assign_expr wsp LBC wsp block_expr wsp RBC )* ELSE wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) | ( ELIF wsp non_assign_expr wsp THEN wsp block_expr | ELIF wsp non_assign_expr wsp LBC wsp block_expr wsp RBC )*? ( ELIF wsp non_assign_expr wsp THEN wsp block_expr wsp END | ELIF wsp non_assign_expr wsp LBC wsp block_expr wsp RBC ) ) | ( THEN wsp block_expr wsp END | LBC wsp block_expr wsp RBC ) ) #IfBlock
| TRY wsp ( block_expr wsp ( EXCEPT (LPR wsp IDN wsp RPR)? wsp ( ( (DO wsp)? LBC wsp block_expr wsp RBC | DO wsp block_expr wsp END | block_expr ) wsp )? FINALLY wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) | EXCEPT (LPR wsp IDN wsp RPR)? wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) ) | ( block_expr wsp END | LBC wsp block_expr wsp RBC ) ) #DebugBlock
| FOR wsp av_var wsp TOR wsp av_inc wsp CMA wsp av_inc wsp ( CMA wsp av_inc wsp )? ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #RangeBlock
| FOR wsp av_var wsp CMA wsp non_assign_expr wsp CMA wsp non_assign_expr wsp CMA wsp non_assign_expr wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #ActionBlock
| FOR wsp IDN wsp ( TOR wsp non_assign_expr )? ( wsp CMA wsp ( IDN wsp ( TOR wsp non_assign_expr )? )? ( wsp CMA wsp IDN wsp TOR wsp non_assign_expr )* )? IN wsp iterable wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #IterationBlock
| ( WHILE wsp non_assign_expr wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) | DO wsp ( LBC wsp block_expr wsp RBC | block_expr ) wsp WHILE wsp non_assign_expr ) #WhileBlock
| ( ( DO | REPEAT ) wsp ( LBC wsp block_expr wsp RBC | block_expr ) wsp UNTIL wsp non_assign_expr | UNTIL wsp non_assign_expr wsp ( DO | REPEAT ) ( LBC wsp block_expr wsp RBC | block_expr wsp END ) ) #RepeatBlock
| isglobal DEF wsp fcreatable wsp fcall wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #FuncBlock
| FUNC wsp fcall wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #CFuncBlock
| LAMBDA wsp fcall wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #LambdaBlock
| SWITCH wsp atompar_option wsp ( DO wsp )? ( LBC wsp (CASE wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )* ( DEFAULT wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )? wsp RBC | (CASE wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )* ( DEFAULT wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )? wsp END ) #SwitchBlock
| DO wsp ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #DoBlock
| LPR block_expr RPR #EnclosedBlockA
| LBC block_expr RBC #EnclosedBlockB
| block #OpenBlock
;
atompar_option
: LPR wsp atom wsp RPR
| atom
;
isglobal: ( GLOBAL wsp )?;
block: ( stat+ wsp (PASS | retstat)* )+ | PASS;
stat
: expression+ wsp SMC*
| expression* wsp SMC+
;
retstat: RETURN wsp non_assign_expr;
expression
: <assoc=right> isglobal var_list ( wsp aop wsp expression )+ #AssignExpr
| exp_list #ExpListA
| non_assign_expr #NonAssign
| atom #AtomEXPR
| IVC #InvalidCharacter
;
literal
: strt
| num
;
datat
: listd
| dictd
| setd
| tupled
;
wsp: WSP*;
listd
: LBR wsp exp_list wsp RBR
| EML
;
dictd
: LBC wsp kvpair wsp
(
CMA
wsp
kvpair
wsp
)*
RBC
;
setd
: LBC wsp exp_list wsp RBC
| EMS
;
indexable
: ( dictd | IDN | ( ( datat | IDN | strt ) ) LBR non_assign_expr RBR | ( datat | IDN | strt ) ( ( DOT | SUP | SIB ) ( datat | IDN | strt ) )+ ) fcall
| ( ( datat | IDN | strt ) ) LBR non_assign_expr RBR
| ( datat | IDN | strt ) ( ( DOT | SUP | SIB ) ( datat | IDN | strt ) )+
| IDN
| datat
;
iterable
: indexable
| strt
;
numidn
: num
| IDN
;
av_numidn
: numidn
| av_var
;
av_inc
: av_numidn
| call
;
tupled: LPR wsp (exp_list | CMA) wsp RPR;
kvpair: non_assign_expr wsp TOR wsp non_assign_expr;
index
: ( iterable ) LBR non_assign_expr RBR
| iterable ( ( DOT | SUP | SIB ) iterable )+
;
var_list: ( typet wsp )? av_var ( wsp CMA wsp ( typet wsp )? var_list)*;
av_var
: IDN
| index
;
exp_list: non_assign_expr (wsp CMA wsp non_assign_expr)*;
atom
: num
| av_var
| strt
| typet
| ckw
| val
| datat
;
aop
: A_FDV // '//='
| A_CDV // '*/='
| A_NOR // '||='
| A_FAC // '=!='
| A_LTE // '=<='
| A_GTE // '=>='
| A_EQL // '==='
| A_NEQ // '!=='
| A_CON // '..='
| A_NXR // '$$='
| A_BRS // '>>='
| A_NND // '&&='
| A_BLS // '<<='
| A_DCL // '::='
| A_CLD // ':.='
| A_KUN // '=**'
| A_VUN // '=*'
| A_DOT // '.='
| A_POW // '^='
| A_NOT // '=!'
| A_BNT // '=~'
| A_LEN // '=#'
| A_PER // '=%'
| A_MUL // '*='
| A_DIV // '/='
| A_MOD // '%='
| A_ADD // '+='
| A_SUB // '-='
| A_LET // '=<'
| A_GRT // '=>'
| A_BND // '&='
| A_BXR // '$='
| A_BOR // '|='
| A_TND // '?='
| A_TOR // ':='
| A_NML // '='
;
num
: exponential
| non_exponential
;
exponential
: PXI
| DXI
| PXF
| DXF
| PXB
| DXB
| PXD
| DXD
| PXP
| DXP
| PRX
| DEX
;
non_exponential
: IMG
| FLT
| DBL
| DCM
| PRC
| INT
;
fcreatable
: dictd
| av_var
;
callablets
: fcreatable
| retblock_expr
| ckw
;
fcall
: CLP
| LPR arg_list RPR
;
call: callablets fcall;
arg_list: arg_type ( wsp CMA wsp arg_type )*;
arg_type
: u_var_list wsp aop wsp u_exp_list
| unkeyed_var
;
unkeyed_var
: LPR var_list RPR
| LBR var_list RBR
| LBC var_list RBC
| var_list
;
u_var_list: unkeyed_var ( wsp aop wsp u_var_list )*;
u_exp_list: unkeyed_exp ( wsp CMA wsp unkeyed_exp )*;
unkeyed_exp
: tupled
| listd
| setd
| non_assign_expr
;
litidn
: literal
| IDN
;
typecast: typet LPR non_assign_expr RPR;
strt
: multi_line
| single_line
| char_string
;
multi_line
: SMT
| USM
| NMT
| UNM
;
single_line
: SST
| USS
| NST
| UNS
| NAS
;
char_string
: SCH
| USC
| NCH
| UNC
| NAC
;
typet
: STRT
| INTT
| NUMT
| DECIMALT
| FLOATT
| DOUBLET
| PRECISET
| EXPNT
| CHART
| IMAGT
| REALT
| HEXTY
| BINTY
| OCTTY
| LISTD
| SETD
| DICTD
| TUPLED
| TYPET
| BOOLT
;
bks_or_WSP
: WSP
| BKS
| SPC
;
emd
: EML
| EMS
;
sep
: SMC
| CMA
| TOR
;
kwr
: WHILE
| FOR
| DO
| DEL
| NEW
| IMPORT
| EXPORT
| DEF
| END
| GLOBAL
| BREAK
| CONTINUE
| NOT
| AND
| OR
| IN
| CASE
| DEFAULT
| RETURN
| TRY
| EXCEPT
| FINALLY
| ELIF
| IF
| ELSE
| AS
| CONST
| REPEAT
| UNTIL
| THEN
| GOTO
| LABEL
| USING
| PUBLIC
| PROTECTED
| PRIVATE
| SELF
| FROM
| XOR
| IMAGT
| REALT
| WHERE
| PASS
| G_G
| L_L
| MAP
| IS
;
ckw
: OPN
| OUT
| OUTF
| PRINT
| PRINTF
| LAMBDA
| FUNC
| ERR
| ERRF
| ASSERT
| ASSERTF
| FORMAT
| SWITCH
| ABS
| ASCII
| CALLABLE
| CHR
| DIR
| EVAL
| EXEC
| FILTER
| GET
| HASH
| ID
| INST
| SUB
| SUPER
| MAX
| MIN
| OBJ
| ORD
| POWF
| REV
| REPR
| ROUND
| FLOOR
| CEIL
| MUL
| SORT
| ADD
| ZIP
| WAIT
| SECS
| MILS
| BENCHMARK
;
val
: RMH // 'inf'
| IMH // 'infi'
| NAN // 'nan'
| IND // 'ind'
| UND // 'und'
| NIL // 'nil'
| NON // 'none'
| TRU // 'true'
| FLS // 'false'
;
opr
: NND // '&&'
| NXR // '$$'
| NOR // '||'
| CLP // '()'
| SUP // '::'
| SIB // ':.'
| KUN // '**'
| INC // '++'
| DEC // '+-'
| FDV // '//'
| CDV // '* /'
| CON // '..'
| BLS // '<<'
| BRS // '>>'
| LTE // '<='
| GTE // '>='
| EQL // '=='
| NEQ // '!='
| LPR // '('
| RPR // ')'
| LBR // '['
| RBR // ']'
| LBC // '{'
| RBC // '}'
| STR // '*'
| POW // '^'
| PLS // '+'
| MNS // '-'
| BNT // '~'
| EXC // '!'
| LEN // '#'
| PER // '%'
| DIV // '/'
| LET // '<'
| GRT // '>'
| BND // '&'
| BXR // '$'
| BOR // '|'
| TND // '?'
| TOR // ':'
| DOT // '.'
;
inl
: strt
| num
| ckw
| kwr
| val
| IDN
| bks_or_WSP
| sep
| emd
| aop
| opr
| typet
| IVC
;
您的 PRINT
令牌只能通过此路径与 blk_expr
规则匹配:
retblock_expr
无法识别以 PRINT
标记开头的任何内容。
因此,您的顺序是 elk_expr
还是 retblock_expr
。
您的语法中没有匹配 PRINT
标记后跟 LPR
标记的解析器规则。 block_expr
由 program
规则匹配,它只匹配(忽略 wsp)block_expr
或 retblock_expr
。这些都没有以 LPR
标记开头的替代项,因此 ANTLR 无法匹配该标记。
print(...)
通常会作为接受 0 个或多个逗号分隔参数的函数调用表达式进行匹配。您不确定 rule/alternative 的定义。 (我 猜测 它应该是 retblock_expr
或 block_expr
的替代方案
这是此错误的直接原因。 ANTLR 确实没有任何 rule/alternative 可以在这个位置接受 LPR
令牌。
当我尝试解析输入时,此 ANTLR4 解析器语法错误 'no viable alternative'。我所知道的唯一匹配输入错误部分的规则是规则 'retblock_expr' 和 'block_expr'。我已将 'retblock_expr' 放在 'block_expr' 前面并将 'non_assign_expr' 放在 'retblock_expr' 前面,但它仍然会引发错误。
输入:
print(do { return a[3] })
完全错误:
line 1:11 no viable alternative at input '(do { return'
解析器语法:
parser grammar TestP;
options { tokenVocab=Test; }
program: ( ( block_expr | retblock_expr ) ( wsp ( block_expr | retblock_expr ) wsp )* wsp )? EOF;
retblock_expr
: isglobal DEF wsp fcreatable wsp fcall wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #FuncBlockA
| FUNC wsp fcall wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #CFuncBlockA
| LAMBDA wsp fcall wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #LambdaBlockA
| SWITCH wsp atompar_option wsp ( DO wsp )? ( LBC wsp (CASE wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )* ( DEFAULT wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )? wsp RBC | (CASE wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )* ( DEFAULT wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )? wsp END ) #SwitchBlockA
| DO wsp ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #DoBlockA
;
non_assign_expr
: ( iterable ( ( DOT | SUP | SIB ) iterable )+ | index ) #AccessExpr
| ( call | datat | LPR non_assign_expr RPR | LBC non_assign_expr RBC | LBR non_assign_expr RBR ) #BracketsExpr
| ( STR | KUN )+ indexable #UnpackExpr
| <assoc=right> non_assign_expr ( wsp POW wsp non_assign_expr )+ #PowExpr
| non_assign_expr ( wsp ( INC | DEC ) wsp non_assign_expr | INC | DEC )+ #CrementExpr
| ( PLS | MNS | BNT | EXC | LEN | NOT )+ non_assign_expr #UnaryExpr
| non_assign_expr EXC+ #FactExpr
| non_assign_expr ( wsp ( STR | DIV | PER | FDV | CDV ) wsp non_assign_expr | PER )+ # AdvExpr
| non_assign_expr ( wsp ( PLS | MNS ) wsp non_assign_expr )+ #BasicExpr
| non_assign_expr ( wsp CON wsp non_assign_expr )+ #ConcatExpr
| non_assign_expr ( wsp ( BLS | BRS ) wsp non_assign_expr )+ #ShiftExpr
| non_assign_expr ( wsp ( LET | LTE | GRT | GTE ) wsp non_assign_expr )+ #CompareExpr
| non_assign_expr ( wsp ( EQL | IS | NEQ | IS wsp NOT ) wsp non_assign_expr )+ #EqualExpr
| non_assign_expr ( wsp BND wsp non_assign_expr )+ #BitAnd
| non_assign_expr ( wsp BXR wsp non_assign_expr )+ #BitXor
| non_assign_expr ( wsp BOR wsp non_assign_expr )+ #BitOr
| <assoc=right> non_assign_expr ( wsp ( AND | TND ) wsp non_assign_expr wsp ( OR | TOR ) wsp non_assign_expr )+ #Ternary
| non_assign_expr ( wsp ( NND | AND ) wsp non_assign_expr )+ #AndExpr
| non_assign_expr ( wsp ( NXR | XOR ) wsp non_assign_expr )+ #XorExpr
| non_assign_expr ( wsp ( NOR | OR ) wsp non_assign_expr )+ #OrExpr
| retblock_expr #RBlockA
| typet LPR non_assign_expr RPR #TypeCastA
| atom #AtomNAE
;
block_expr
: IF wsp non_assign_expr wsp ( ( THEN wsp block_expr | LBC wsp block_expr wsp RBC ) wsp ( ( ELIF wsp non_assign_expr wsp THEN wsp block_expr | ELIF wsp non_assign_expr wsp LBC wsp block_expr wsp RBC )* ELSE wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) | ( ELIF wsp non_assign_expr wsp THEN wsp block_expr | ELIF wsp non_assign_expr wsp LBC wsp block_expr wsp RBC )*? ( ELIF wsp non_assign_expr wsp THEN wsp block_expr wsp END | ELIF wsp non_assign_expr wsp LBC wsp block_expr wsp RBC ) ) | ( THEN wsp block_expr wsp END | LBC wsp block_expr wsp RBC ) ) #IfBlock
| TRY wsp ( block_expr wsp ( EXCEPT (LPR wsp IDN wsp RPR)? wsp ( ( (DO wsp)? LBC wsp block_expr wsp RBC | DO wsp block_expr wsp END | block_expr ) wsp )? FINALLY wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) | EXCEPT (LPR wsp IDN wsp RPR)? wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) ) | ( block_expr wsp END | LBC wsp block_expr wsp RBC ) ) #DebugBlock
| FOR wsp av_var wsp TOR wsp av_inc wsp CMA wsp av_inc wsp ( CMA wsp av_inc wsp )? ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #RangeBlock
| FOR wsp av_var wsp CMA wsp non_assign_expr wsp CMA wsp non_assign_expr wsp CMA wsp non_assign_expr wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #ActionBlock
| FOR wsp IDN wsp ( TOR wsp non_assign_expr )? ( wsp CMA wsp ( IDN wsp ( TOR wsp non_assign_expr )? )? ( wsp CMA wsp IDN wsp TOR wsp non_assign_expr )* )? IN wsp iterable wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #IterationBlock
| ( WHILE wsp non_assign_expr wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) | DO wsp ( LBC wsp block_expr wsp RBC | block_expr ) wsp WHILE wsp non_assign_expr ) #WhileBlock
| ( ( DO | REPEAT ) wsp ( LBC wsp block_expr wsp RBC | block_expr ) wsp UNTIL wsp non_assign_expr | UNTIL wsp non_assign_expr wsp ( DO | REPEAT ) ( LBC wsp block_expr wsp RBC | block_expr wsp END ) ) #RepeatBlock
| isglobal DEF wsp fcreatable wsp fcall wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #FuncBlock
| FUNC wsp fcall wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #CFuncBlock
| LAMBDA wsp fcall wsp ( DO wsp )? ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #LambdaBlock
| SWITCH wsp atompar_option wsp ( DO wsp )? ( LBC wsp (CASE wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )* ( DEFAULT wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )? wsp RBC | (CASE wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )* ( DEFAULT wsp atompar_option wsp ( block_expr wsp END | LBC wsp block_expr wsp RBC ) )? wsp END ) #SwitchBlock
| DO wsp ( LBC wsp block_expr wsp RBC | block_expr wsp END ) #DoBlock
| LPR block_expr RPR #EnclosedBlockA
| LBC block_expr RBC #EnclosedBlockB
| block #OpenBlock
;
atompar_option
: LPR wsp atom wsp RPR
| atom
;
isglobal: ( GLOBAL wsp )?;
block: ( stat+ wsp (PASS | retstat)* )+ | PASS;
stat
: expression+ wsp SMC*
| expression* wsp SMC+
;
retstat: RETURN wsp non_assign_expr;
expression
: <assoc=right> isglobal var_list ( wsp aop wsp expression )+ #AssignExpr
| exp_list #ExpListA
| non_assign_expr #NonAssign
| atom #AtomEXPR
| IVC #InvalidCharacter
;
literal
: strt
| num
;
datat
: listd
| dictd
| setd
| tupled
;
wsp: WSP*;
listd
: LBR wsp exp_list wsp RBR
| EML
;
dictd
: LBC wsp kvpair wsp
(
CMA
wsp
kvpair
wsp
)*
RBC
;
setd
: LBC wsp exp_list wsp RBC
| EMS
;
indexable
: ( dictd | IDN | ( ( datat | IDN | strt ) ) LBR non_assign_expr RBR | ( datat | IDN | strt ) ( ( DOT | SUP | SIB ) ( datat | IDN | strt ) )+ ) fcall
| ( ( datat | IDN | strt ) ) LBR non_assign_expr RBR
| ( datat | IDN | strt ) ( ( DOT | SUP | SIB ) ( datat | IDN | strt ) )+
| IDN
| datat
;
iterable
: indexable
| strt
;
numidn
: num
| IDN
;
av_numidn
: numidn
| av_var
;
av_inc
: av_numidn
| call
;
tupled: LPR wsp (exp_list | CMA) wsp RPR;
kvpair: non_assign_expr wsp TOR wsp non_assign_expr;
index
: ( iterable ) LBR non_assign_expr RBR
| iterable ( ( DOT | SUP | SIB ) iterable )+
;
var_list: ( typet wsp )? av_var ( wsp CMA wsp ( typet wsp )? var_list)*;
av_var
: IDN
| index
;
exp_list: non_assign_expr (wsp CMA wsp non_assign_expr)*;
atom
: num
| av_var
| strt
| typet
| ckw
| val
| datat
;
aop
: A_FDV // '//='
| A_CDV // '*/='
| A_NOR // '||='
| A_FAC // '=!='
| A_LTE // '=<='
| A_GTE // '=>='
| A_EQL // '==='
| A_NEQ // '!=='
| A_CON // '..='
| A_NXR // '$$='
| A_BRS // '>>='
| A_NND // '&&='
| A_BLS // '<<='
| A_DCL // '::='
| A_CLD // ':.='
| A_KUN // '=**'
| A_VUN // '=*'
| A_DOT // '.='
| A_POW // '^='
| A_NOT // '=!'
| A_BNT // '=~'
| A_LEN // '=#'
| A_PER // '=%'
| A_MUL // '*='
| A_DIV // '/='
| A_MOD // '%='
| A_ADD // '+='
| A_SUB // '-='
| A_LET // '=<'
| A_GRT // '=>'
| A_BND // '&='
| A_BXR // '$='
| A_BOR // '|='
| A_TND // '?='
| A_TOR // ':='
| A_NML // '='
;
num
: exponential
| non_exponential
;
exponential
: PXI
| DXI
| PXF
| DXF
| PXB
| DXB
| PXD
| DXD
| PXP
| DXP
| PRX
| DEX
;
non_exponential
: IMG
| FLT
| DBL
| DCM
| PRC
| INT
;
fcreatable
: dictd
| av_var
;
callablets
: fcreatable
| retblock_expr
| ckw
;
fcall
: CLP
| LPR arg_list RPR
;
call: callablets fcall;
arg_list: arg_type ( wsp CMA wsp arg_type )*;
arg_type
: u_var_list wsp aop wsp u_exp_list
| unkeyed_var
;
unkeyed_var
: LPR var_list RPR
| LBR var_list RBR
| LBC var_list RBC
| var_list
;
u_var_list: unkeyed_var ( wsp aop wsp u_var_list )*;
u_exp_list: unkeyed_exp ( wsp CMA wsp unkeyed_exp )*;
unkeyed_exp
: tupled
| listd
| setd
| non_assign_expr
;
litidn
: literal
| IDN
;
typecast: typet LPR non_assign_expr RPR;
strt
: multi_line
| single_line
| char_string
;
multi_line
: SMT
| USM
| NMT
| UNM
;
single_line
: SST
| USS
| NST
| UNS
| NAS
;
char_string
: SCH
| USC
| NCH
| UNC
| NAC
;
typet
: STRT
| INTT
| NUMT
| DECIMALT
| FLOATT
| DOUBLET
| PRECISET
| EXPNT
| CHART
| IMAGT
| REALT
| HEXTY
| BINTY
| OCTTY
| LISTD
| SETD
| DICTD
| TUPLED
| TYPET
| BOOLT
;
bks_or_WSP
: WSP
| BKS
| SPC
;
emd
: EML
| EMS
;
sep
: SMC
| CMA
| TOR
;
kwr
: WHILE
| FOR
| DO
| DEL
| NEW
| IMPORT
| EXPORT
| DEF
| END
| GLOBAL
| BREAK
| CONTINUE
| NOT
| AND
| OR
| IN
| CASE
| DEFAULT
| RETURN
| TRY
| EXCEPT
| FINALLY
| ELIF
| IF
| ELSE
| AS
| CONST
| REPEAT
| UNTIL
| THEN
| GOTO
| LABEL
| USING
| PUBLIC
| PROTECTED
| PRIVATE
| SELF
| FROM
| XOR
| IMAGT
| REALT
| WHERE
| PASS
| G_G
| L_L
| MAP
| IS
;
ckw
: OPN
| OUT
| OUTF
| PRINT
| PRINTF
| LAMBDA
| FUNC
| ERR
| ERRF
| ASSERT
| ASSERTF
| FORMAT
| SWITCH
| ABS
| ASCII
| CALLABLE
| CHR
| DIR
| EVAL
| EXEC
| FILTER
| GET
| HASH
| ID
| INST
| SUB
| SUPER
| MAX
| MIN
| OBJ
| ORD
| POWF
| REV
| REPR
| ROUND
| FLOOR
| CEIL
| MUL
| SORT
| ADD
| ZIP
| WAIT
| SECS
| MILS
| BENCHMARK
;
val
: RMH // 'inf'
| IMH // 'infi'
| NAN // 'nan'
| IND // 'ind'
| UND // 'und'
| NIL // 'nil'
| NON // 'none'
| TRU // 'true'
| FLS // 'false'
;
opr
: NND // '&&'
| NXR // '$$'
| NOR // '||'
| CLP // '()'
| SUP // '::'
| SIB // ':.'
| KUN // '**'
| INC // '++'
| DEC // '+-'
| FDV // '//'
| CDV // '* /'
| CON // '..'
| BLS // '<<'
| BRS // '>>'
| LTE // '<='
| GTE // '>='
| EQL // '=='
| NEQ // '!='
| LPR // '('
| RPR // ')'
| LBR // '['
| RBR // ']'
| LBC // '{'
| RBC // '}'
| STR // '*'
| POW // '^'
| PLS // '+'
| MNS // '-'
| BNT // '~'
| EXC // '!'
| LEN // '#'
| PER // '%'
| DIV // '/'
| LET // '<'
| GRT // '>'
| BND // '&'
| BXR // '$'
| BOR // '|'
| TND // '?'
| TOR // ':'
| DOT // '.'
;
inl
: strt
| num
| ckw
| kwr
| val
| IDN
| bks_or_WSP
| sep
| emd
| aop
| opr
| typet
| IVC
;
您的 PRINT
令牌只能通过此路径与 blk_expr
规则匹配:
retblock_expr
无法识别以 PRINT
标记开头的任何内容。
因此,您的顺序是 elk_expr
还是 retblock_expr
。
您的语法中没有匹配 PRINT
标记后跟 LPR
标记的解析器规则。 block_expr
由 program
规则匹配,它只匹配(忽略 wsp)block_expr
或 retblock_expr
。这些都没有以 LPR
标记开头的替代项,因此 ANTLR 无法匹配该标记。
print(...)
通常会作为接受 0 个或多个逗号分隔参数的函数调用表达式进行匹配。您不确定 rule/alternative 的定义。 (我 猜测 它应该是 retblock_expr
或 block_expr
这是此错误的直接原因。 ANTLR 确实没有任何 rule/alternative 可以在这个位置接受 LPR
令牌。