ANTLR4:错误的输入错误

本文关键字:错误 输入 ANTLR4 | 更新日期: 2023-09-27 18:36:55

我正在为我目前正在处理的自定义脚本编写解析器。

当我在基本脚本下面输入时:

if (db.Title == 2) { }

这应该在conditionStatement上匹配.但是当我运行它时,我得到以下错误。当我尝试输入for循环输入时,会发生同样的错误:

line 1:0 extraneous input 'if'

这是我的语法:

grammar CustomScript;
/*
 * Parser Rules
 */
prog
    :   compoundScript EOF
    ;
compoundScript
    :  ( '{' script '}' )+
    |  ( script )
    ;
script
    :   (declaration* statement*)
    |   statement*
    ;
iterationStatement
    :   'for' '(' identifier 'in' collection ')' statement
    ;
collection
    :   list|data | identifier
    ;
statement
    :   expressionStatement
    |   conditionStatement
    |   iterationStatement
    |   '{' statement '}'
    ;
conditionStatement
    :   'if' '(' expression ')' statement ('else' statement)?
    ;
expressionStatement
    :   expression ';'?
    ;
declaration
    :   constantObjectDeclaration+
    ;
constantObjectDeclaration
    :   'set' identifier 'as' constantObject ';'?
    ;
constantObject
    :   identifier '.' identifier '[' value ']'
    ;
expression
    :   assignmentExpression
    |   expression ',' assignmentExpression
    ;
assignmentExpression
    :   postfixExpression assignmentOperator=AssignmentOperator postfixExpression    
    |   conditionalExpression
    ;
conditionalExpression
    :   logicalOrExpression ('?' expression ':' conditionalExpression)?
    ;
logicalOrExpression
    :   logicalAndExpression
    |   logicalOrExpression '||' logicalAndExpression
    ;
logicalAndExpression
    :   logicalCondition
    |   logicalAndExpression '&&' logicalCondition
    ;
postfixExpression
    :   primaryExpression       
    |   postfixExpression '[' expression ']'
    |   postfixExpression '.' Advance '.' Digits '.' identifier
    |   postfixExpression '.' Main '.' Digits '.' identifier
    |   postfixExpression '.' Split '.' Digits '.' identifier       
    |   postfixExpression '++'          // Ensure only variable++
    |   postfixExpression '--'          // Ensure only variable--
    ;
primaryExpression
    :   identifier
    |   constant
    |   stringLiteral+
    |   calcExpr                        
    |   list
    |   '(' expression ')'
    ;
calcExpr 
    :   calcExpr op=(MulDivOperator | '^') calcExpr  # MulDivExpo
    |   calcExpr op=AddSubOperator calcExpr          # AddSub
    |   number                                       # IntValue
    |   data                                         # DataValue
    |   identifier                                   # IdentifierValue
    |   constant                                     # ConstantValue
    |   '(' calcExpr ')'                             # ExprWithParens
    ;
logicalCondition
    :   data instructionOption number           # LeftDataRightNumber
    |   number instructionOption data           # LeftNumberRightData
    |   data instructionOption data             # LeftDataRightData
    |   constant instructionOption DateTime     # LeftConstantRightDateTime
    |   data instructionOption DateTime         # LeftDataRightDateTime
    |   DateTime instructionOption data         # LeftDateTimeRightData 
    |   DateTime instructionOption constant     # LeftDateTimeRightConstant
    |   data instructionOption String           # LeftDataRightString
    |   String instructionOption data           # LeftStringRightData
    |   String instructionOption constant       # LeftStringRightConstant
    |   constant instructionOption constant     # LeftConstantRightConstant
    |   constant instructionOption String       # LeftConstantRightString
    |   constant instructionOption number       # LeftConstantRightNumber
    |   number instructionOption constant       # LeftNumberRightConstant
    |   constant instructionOption data         # LeftConstantRightData
    |   data instructionOption constant         # LeftDataRightConstant
    |   identifier instructionOption constant   # LeftIdentifierRightConstant
    |   constant instructionOption identifier   # LeftConstantRightIdentifier
    |   identifier instructionOption data       # LeftIdentifierRightData
    |   data instructionOption identifier       # LeftDataRightIdentifier
    |   data In list                    # LeftDataInRightList
    |   constant In list                # LeftConstantInRightList
    |   value In list                   # LeftValueInRightList
    |   identifier In list              # LeftIdentifierInRightList
    |   '(' logicalCondition ')'        # ConditionWithParens
    ;
instructionOption
    :   Keyword | Operator | AssignmentOperator | MulDivOperator | AddSubOperator
    ;
list 
    :   ( '[' ( identifierList )? ']' )
    ;

identifierList
    :   ( identifier ','? )
    |   ( (identifier ',' )+ (identifier ','? ) )+
    ;
value 
    :   number
    |   stringLiteral
    ;
constant 
    :   (('$''{') (NonDigit | DigitsNondigits) '}')
    ;
data 
    :   identifier '.' (MetaData '.')? identifier
    ;
datetime 
    :   Quote Digits '-' Digits '-' Digits Quote
    |   Quote Digits '/' Digits '/' Digits Quote
    |   Quote Digits '-' Digits '-' Digits Space Digits ':' Digits Quote
    |   Quote Digits '/' Digits '/' Digits Space Digits ':' Digits Quote
    ;
deliveryType 
    :   Advances | Mains | Splits 
    ;
number 
    :   Digits (Dot Digits)?
    ;
Keyword
    :   Else
    |   For
    |   If
    |   Before
    |   Contains
    |   After
    |   And
    |   Or
    |   In
    |   Set
    |   StartsWith
    |   EndsWith
    ;
separator 
    :   '-' | '/' | ':'
    ;
identifier 
    :   NonDigit | DigitsNondigits
    ;
NonDigit 
    :   [a-zA-Z_]+
    ;
DigitsNondigits 
    :   [a-zA-Z0-9_]+
    ;
Digits
    :   [0-9]+
    ;
stringLiteral
    :   Quote SCharSequence? Quote
    ;
Quote 
    :   (''"'|'''') -> channel(HIDDEN)
    ;
fragment
SCharSequence
    :   SChar+
    ;
fragment
SChar
    :   ~["'''r'n']
    |   EscapeSequence
    ;
fragment
EscapeSequence
    :   SimpleEscapeSequence
    ;
fragment
SimpleEscapeSequence
    :   '''' ['"?abfnrtv'']
    ;
//fragment
AssignmentOperator
    :   '='
    |   '*='
    |   '/='
    |   '%='
    |   '+='
    |   '-='
    |   '^='
    ;
MulDivOperator
    :   '*'
    |   '/'
    ;
AddSubOperator
    :   '+'
    |   '-'
    ;
Operator
    :   '%'
    |   '&'
    |   '!'
    |   '<'
    |   '>'
    |   '=='
    |   '!='
    |   '<='
    |   '>='
    |   '&&'
    |   '||'
    |   '++'
    |   '--'
    |   ','
    ;    
/*
 * Lexer Rules
 */
Deliveries      : 'Deliveries';
Advances        : 'Advances';
Mains           : 'Mains';
Splits          : 'Splits';
Else            : 'else';
For             : 'for';
If              : 'if';
Advance         : 'Advance';
Main            : 'Main';
Split           : 'Split';
Before          : 'before';
Contains        : 'contains';
After           : 'after';
And             : 'and';
Or              : 'or';
In              : 'in';
Set             : 'Set';
StartsWith      : 'startsWith';
EndsWith        : 'endsWith';
MetaData        : 'MetaData';
//LeftParen       : '(';
//RightParen      : ')';
LeftBracket     : '[';
RightBracket    : ']';
//LeftBrace       : '{';
//RightBrace      : '}';
Less            : '<';
LessEqual       : '<=';
Greater         : '>';
GreaterEqual    : '>=';
Plus            : '+';
PlusPlus        : '++';
Minus           : '-';
MinusMinus      : '--';
Star            : '*';
Div             : '/';
Mod             : '%';
AndAnd          : '&&';
OrOr            : '||';
Caret           : '^';
Not             : '!';
Question        : '?';
Colon           : ':';
Semi            : ';';
Comma           : ',';
Assign          : '=';
StarAssign      : '*=';
ExpoAssign      : '^=';
DivAssign       : '/=';
ModAssign       : '%=';
PlusAssign      : '+=';
MinusAssign     : '-=';
Equal           : '==';
NotEqual        : '!=';
Space           : ' ' -> skip;
DoubleQuote     : '"';
Dot             : '.';
NewLine         : (''r' ''n' ? | ''n') -> skip;
BlockComment    : '/*' .*? '*/' -> skip;
LineCommentOption1  : '//' ~['r'n]* -> skip;
LineCommentOption2  : '#' ~['r'n]* -> skip;
WS  :   (''r' | ''n' | ''t') -> channel(HIDDEN);

注意

已编辑:由于原始表达式输入错误问题已解决 - 使用上述语法。另请注意,赏金说明中"No viable alternative input"指出的list表达式问题也通过上述编辑的语法得到解决。

ANTLR4:错误的输入错误

  • 始终删除控制台输出中的警告。在您的情况下: warning(125): expr.g4:114:35: implicit definition of token 'DateTime' in parser warning(125): expr.g4:119:31: implicit definition of token 'String' in parser warning(125): expr.g4:234:14: implicit definition of token 'SCharSequence' in parser 显式定义所有令牌(我将日期时间替换为日期时间)。
  • 不能在解析器规则 (SCharSequence) 中使用片段规则。还要尽量不要在其他令牌中使用令牌。
  • 将关键字(if、else、for 等)标记放在更常见的 tokn(id、数字等)之前。
  • 如果可能的话,尽量避免左递归(在你的例子中是表达式和赋值表达式)。并尽可能使用 EBNF 的强大功能。

因此,有我的语法更正版本,它可以解析您的示例表达式而不会出错:

grammar expr;
/*
 * Parser Rules
 */
prog
    :   compoundScript EOF
    ;
compoundScript
    :  ( '{' script '}' )+
    |  ( script )
    ;
script
    :   (declaration* statement*)
    |   statement*
    ;
iterationStatement
    :   'for' '(' identifier 'in' collection ')' statement
    ;
collection
    :   list|data | identifier
    ;
statement
    :   expressionStatement
    |   conditionStatement
    |   iterationStatement
    |   '{' statement? '}'
    ;
conditionStatement
    :   'if' '(' expression ')' statement ('else' statement)?
    ;
expressionStatement
    :   expression ';'?
    ;
declaration
    :   constantObjectDeclaration+
    ;
constantObjectDeclaration
    :   'set' identifier 'as' constantObject ';'?
    ;
constantObject
    :   identifier '.' identifier '[' value ']'
    ;
expression
    :   assignmentExpression (',' assignmentExpression)*
    ;
assignmentExpression
    :   postfixExpression assignmentOperator=AssignmentOperator postfixExpression    
    |   conditionalExpression
    ;
conditionalExpression
    :   logicalOrExpression ('?' expression ':' conditionalExpression)?
    ;
logicalOrExpression
    :   logicalAndExpression
    |   logicalOrExpression '||' logicalAndExpression
    ;
logicalAndExpression
    :   logicalCondition
    |   logicalAndExpression '&&' logicalCondition
    ;
postfixExpression
    :   primaryExpression       
    |   postfixExpression '[' expression ']'
    |   postfixExpression '.' Advance '.' Digits '.' identifier
    |   postfixExpression '.' Main '.' Digits '.' identifier
    |   postfixExpression '.' Split '.' Digits '.' identifier       
    |   postfixExpression '++'          // Ensure only variable++
    |   postfixExpression '--'          // Ensure only variable--
    ;
primaryExpression
    :   identifier
    |   constant
    |   StringLiteral+
    |   calcExpr                        
    |   list
    |   '(' expression ')'
    ;
calcExpr 
    :   calcExpr op=(MulDivOperator | '^') calcExpr  # MulDivExpo
    |   calcExpr op=AddSubOperator calcExpr          # AddSub
    |   number                                       # IntValue
    |   data                                         # DataValue
    |   identifier                                   # IdentifierValue
    |   constant                                     # ConstantValue
    |   '(' calcExpr ')'                             # ExprWithParens
    ;
logicalCondition
    :   data instructionOption number           # LeftDataRightNumber
    |   number instructionOption data           # LeftNumberRightData
    |   data instructionOption data             # LeftDataRightData
    |   constant instructionOption datetime     # LeftConstantRightDateTime
    |   data instructionOption datetime         # LeftDataRightDateTime
    |   datetime instructionOption data         # LeftDateTimeRightData 
    |   datetime instructionOption constant     # LeftDateTimeRightConstant
    |   data instructionOption StringLiteral           # LeftDataRightString
    |   StringLiteral instructionOption data           # LeftStringRightData
    |   StringLiteral instructionOption constant       # LeftStringRightConstant
    |   constant instructionOption constant     # LeftConstantRightConstant
    |   constant instructionOption StringLiteral       # LeftConstantRightString
    |   constant instructionOption number       # LeftConstantRightNumber
    |   number instructionOption constant       # LeftNumberRightConstant
    |   constant instructionOption data         # LeftConstantRightData
    |   data instructionOption constant         # LeftDataRightConstant
    |   identifier instructionOption constant   # LeftIdentifierRightConstant
    |   constant instructionOption identifier   # LeftConstantRightIdentifier
    |   identifier instructionOption data       # LeftIdentifierRightData
    |   data instructionOption identifier       # LeftDataRightIdentifier
    |   data In list                    # LeftDataInRightList
    |   constant In list                # LeftConstantInRightList
    |   value In list                   # LeftValueInRightList
    |   identifier In list              # LeftIdentifierInRightList
    |   '(' logicalCondition ')'        # ConditionWithParens
    ;
instructionOption
    :   keyword | Operator | AssignmentOperator | MulDivOperator | AddSubOperator
    ;
list 
    :   LeftBracket (dataList |  constantList | valueList |  identifierList)? RightBracket
    ;
dataList
    :   data ( Comma data )*
    ;
constantList
    :   constant ( Comma constant )*
    ;
valueList
    :   value ( Comma value )*
    ;
identifierList
    :   identifier ( Comma identifier )*
    ;
value 
    :   number
    |   StringLiteral
    ;
constant 
    :   (('$''{') (NonDigit | DigitsNondigits) '}')
    ;
data 
    :   identifier '.' (MetaData '.')? identifier
    ;
datetime 
    :   Quote Digits '-' Digits '-' Digits Quote
    |   Quote Digits '/' Digits '/' Digits Quote
    |   Quote Digits '-' Digits '-' Digits Space Digits ':' Digits Quote
    |   Quote Digits '/' Digits '/' Digits Space Digits ':' Digits Quote
    ;
deliveryType 
    :   Advances | Mains | Splits 
    ;
number 
    :   Digits (Dot Digits)?
    ;
keyword
    :   Else
    |   For
    |   If
    |   Before
    |   Contains
    |   After
    |   And
    |   Or
    |   In
    |   Set
    |   StartsWith
    |   EndsWith
    ;
separator 
    :   '-' | '/' | ':'
    ;
identifier 
    :   NonDigit | DigitsNondigits
    ;
//fragment
AssignmentOperator
    :   '='
    |   '*='
    |   '/='
    |   '%='
    |   '+='
    |   '-='
    |   '^='
    ;
MulDivOperator
    :   '*'
    |   '/'
    ;
AddSubOperator
    :   '+'
    |   '-'
    ;
Operator
    :   '%'
    |   '&'
    |   '!'
    |   '<'
    |   '>'
    |   '=='
    |   '!='
    |   '<='
    |   '>='
    |   '&&'
    |   '||'
    |   '++'
    |   '--'
    ;
/*
 * Lexer Rules
 */
Deliveries      : 'Deliveries';
Advances        : 'Advances';
Mains           : 'Mains';
Splits          : 'Splits';
Else            : 'else';
For             : 'for';
If              : 'if';
Advance         : 'Advance';
Main            : 'Main';
Split           : 'Split';
Before          : 'before';
Contains        : 'contains';
After           : 'after';
And             : 'and';
Or              : 'or';
In              : 'in';
Set             : 'Set';
StartsWith      : 'startsWith';
EndsWith        : 'endsWith';
MetaData        : 'MetaData';
//LeftParen       : '(';
//RightParen      : ')';
LeftBracket     : '[';
RightBracket    : ']';
//LeftBrace       : '{';
//RightBrace      : '}';
Less            : '<';
LessEqual       : '<=';
Greater         : '>';
GreaterEqual    : '>=';
Plus            : '+';
PlusPlus        : '++';
Minus           : '-';
MinusMinus      : '--';
Star            : '*';
Div             : '/';
Mod             : '%';
AndAnd          : '&&';
OrOr            : '||';
Caret           : '^';
Not             : '!';
Question        : '?';
Colon           : ':';
Semi            : ';';
Comma           : ',';
Assign          : '=';
StarAssign      : '*=';
ExpoAssign      : '^=';
DivAssign       : '/=';
ModAssign       : '%=';
PlusAssign      : '+=';
MinusAssign     : '-=';
Equal           : '==';
NotEqual        : '!=';
Space           : ' ' -> skip;
DoubleQuote     : '"';
Dot             : '.';
NewLine         : (''r' ''n' ? | ''n') -> skip;
BlockComment    : '/*' .*? '*/' -> skip;
LineCommentOption1  : '//' ~['r'n]* -> skip;
LineCommentOption2  : '#' ~['r'n]* -> skip;
WS  :   (''r' | ''n' | ''t') -> channel(HIDDEN);
NonDigit 
    :   [a-zA-Z_]+
    ;
Digits
    :   [0-9]+
    ;   
DigitsNondigits 
    :   [a-zA-Z0-9_]+
    ;
StringLiteral
    :   Quote SCharSequence? Quote
    ;
Quote 
    :   (''"'|'''') -> channel(HIDDEN)
    ;
fragment SCharSequence
    :   SChar+
    ;
fragment
SChar
    :   ~["'''r'n']
    |   EscapeSequence
    ;
fragment
EscapeSequence
    :   SimpleEscapeSequence
    ;
fragment
SimpleEscapeSequence
    :   '''' ['"?abfnrtv'']
    ;