我需要一个语法来解析分隔标记的双点,如:
1..5
,v[1]..v[2]
或1+f(1)..2+v[f(2)]..3+f(3)
。
基本上,这些标记表示整数范围,例如,1..5
表示范围1到5的整数。标记文字只应表示为" Integer..Integer"
我还必须解析一些整数文字和真正的文字。 所以目前,我有一个自下而上的语法:
unary_expr
: range_expr # ToRangeExpr
| PLUS rhs=unary_expr # UnaryPlusExpr
| MINUS rhs=unary_expr # UnaryMinusExpr
| NOT rhs=unary_expr # UnaryNotExpr
;
range_expr
: index_expr # ToIndexExpr
| lhs=index_expr RANGEDOT rhs=index_expr # RangeExpr
| lhs=range_literal rhs=index_expr # RangeLiteralExpr
;
index_expr
: atom # ToAtom
| atom LBRACK expression RBRACK # IndexExpr
;
atom
: vector_atom # ToVectorAtom
| matrix_atom # ToMatrixAtom
| boolean_literal # ToBooleanLiteral
| int_literal # ToIntegerLiteral
| real_literal # ToRealLiteral
| char_literal # ToCharLiteral
| string_literal # ToStringLiteral
| tuple_literal # ToTupleLiteral
| range_literal # ToRangeLiteral
| tuple_element # ToTupleElement
| type_cast # ToTypeCast
| stream_state # ToStreamState
| function_call # ToFunctionCall
| ID # IDAtom
| IDENTITY # IdentityLiteral
| NULL # NullLiteral
| LPAREN expression RPAREN # ToSubExpr
range_literal: RANGE_LITERAL;
RANGE_LITERAL
: INT_LITERAL RANGEDOT INT_LITERAL
;
REAL_LITERAL
: DOT US+ INT_LITERAL REAL_EXP?
| INT_LITERAL DOT US* INT_LITERAL? REAL_EXP?
| INT_LITERAL REAL_EXP
| DOT INT_LITERAL REAL_EXP
;
REAL_EXP
: 'e' US* (PLUS | MINUS |)? US* INT_LITERAL
;
INT_LITERAL: NUM (NUM | US)*;
目前,我的语法可以解析多整数链式范围标记。但是,我无法解析任何多表达式链接范围标记。我试图将range_expr
更改为(使其更加模糊):
range_expr
: range_literal
| index_expr (RANGEDOT index_expr*)
;
但是,它并没有改变我的解析敏感度。那么我应该做些什么改变让我的语法解析多个index_expr
链式范围标记?
答案 0 :(得分:1)
我无法重复使用你的语法(因为缺少词法分析器/解析器规则)但是如果我正确理解了这个问题:你想要一个简单的两个数字范围或者将任意数量的{{{ 1}}。这样做的想法是在expr
中创建一个子规则,该子规则将匹配数字范围(index_expr
的专用版本),并具有exprChain
的递归定义,该定义将由链接表达式(expr
)。
作为这个想法的一个例子,我介绍了小语法。
exprChain
此示例语法能够匹配您提到的所有远程表达式:grammar test;
INT : [0-9]+;
REAL : [0-9]* '.' [0-9]+;
NAME : [a-zA-Z]+;
numeric
: INT | REAL
;
reference
: NAME # variable
| NAME '[' expr ']' # array
| NAME '(' expr ')' # functionCall
;
index_expr
: numeric '..' numeric # rangeOfNumbers
| expr # classicExpr
;
expr
: expr '+' expr # exprAdd
| reference # exprRef
| numeric # exprNumber
| expr '..' expr # exprChain
;
或1..5
(作为.1...3
),rangeOfNumbers
或v[1]..v[2]
(两者)作为1+f(1)..2+v[f(2)]..3+f(3)
)。
答案 1 :(得分:0)
问题是我无法在语法中将range_expr
视为unary_expr
,因为它会将antlr4与real_literal
选项混淆,并强制使用antlr4匹配{{1} }令牌(即logic_expr
,xor
,我没有在我的问题中显示它们。在我的微观修复之后,部分语法将是:
or