xtext中的终端/数据类型/解析器规则 [英] terminal/datatype/parser rules in xtext
问题描述
我正在使用xtext 2.4.
我想做的是一种类似SQL的语法.
让我感到困惑的是,我不确定应该将哪些东西视为终端/数据类型/解析器规则.到目前为止,我与MyTerm
相关的语法是:
I'm using xtext 2.4.
What I want to do is a SQL-like syntax.
The things confuse me are I'm not sure which things should be treated as terminal/datatype/parser rules. So far my grammar related to MyTerm
is:
Model:
(terms += MyTerm ';')*
;
MyTerm:
constant=MyConstant | variable?='?'| collection_literal=CollectionLiteral
;
MyConstant
: string=STRING
| number=MyNumber
| date=MYDATE
| uuid=UUID
| boolean=MYBOOLEAN
| hex=BLOB
;
MyNumber:
int=SIGNINT | float=SIGNFLOAT
;
SIGNINT returns ecore::EInt:
'-'? INT
;
SIGNFLOAT returns ecore::EFloat:
'-'? INT '.' INT;
;
CollectionLiteral:
=> MapLiteral | SetLiteral | ListLiteral
;
MapLiteral:
'{' {MapLiteral} (entries+=MapEntry (',' entries+=MapEntry)* )? '}'
;
MapEntry:
key=MyTerm ':' value=MyTerm
;
SetLiteral:
'{' {SetLiteral} (values+=MyTerm (',' values+=MyTerm)* )+ '}'
;
ListLiteral:
'[' {ListLiteral} ( values+=MyTerm (',' values+=MyTerm)* )? ']'
;
terminal MYDATE:
'0'..'9' '0'..'9' '0'..'9' '0'..'9' '-'
'0'..'9' '0'..'9' '-'
'0'..'9' '0'..'9'
;
terminal HEX:
'a'..'h'|'A'..'H'|'0'..'9'
;
terminal UUID:
HEX HEX HEX HEX HEX HEX HEX HEX '-'
HEX HEX HEX HEX '-'
HEX HEX HEX HEX '-'
HEX HEX HEX HEX '-'
HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX
;
terminal BLOB:
'0' ('x'|'X') HEX+
;
terminal MYBOOLEAN returns ecore::EBoolean:
'true' | 'false' | 'TRUE' | 'FALSE'
;
几个问题:
-
如何用符号定义整数?如果我定义另一个终端规则
terminal SIGNINT: '-'? '0'..'9'+;
,则antlr将抱怨INT无法访问.因此,我将其定义为数据类型规则SIGNINT: '-'? INT;
这是正确的方法吗?
How to define integer with sign? If I define another terminal rule
terminal SIGNINT: '-'? '0'..'9'+;
, antlr will complain about INT becoming unreachable. Therefore I define it as a datatype ruleSIGNINT: '-'? INT;
Is this the correct way to do it?
如何用符号定义浮点数?我做的和定义带符号SIGNFLOAT: '-'? INT '.' INT;
的整数完全一样,不确定这是否正确.
How to define float with sign? I did exactly the same as define integer with sign, SIGNFLOAT: '-'? INT '.' INT;
, not sure if this is correct as well.
如何定义日期规则?我想使用解析器规则在字段中存储年/月/日信息,但将其定义为MyDate: year=INT '-' month=INT '-' date=INT;
antlr会抱怨Decision can match input such as "RULE_INT '-' RULE_INT '-' RULE_INT" using multiple alternatives: 2, 3
As a result, alternative(s) 3 were disabled for that input
How to define a date rule? I want to use a parser rule to store year/month/day info in fields, but define it as MyDate: year=INT '-' month=INT '-' date=INT;
antlr will complain Decision can match input such as "RULE_INT '-' RULE_INT '-' RULE_INT" using multiple alternatives: 2, 3
As a result, alternative(s) 3 were disabled for that input
我还有其他一些规则,例如
I also have some other rules like
以下
RelationCompare:
name=ID compare=COMPARE term=MyTerm
;
,但a=4
将不是有效的RelationCompare
,因为a
和4
将被视为HEX
.我发现这是因为,如果我将关系更改为j=44
,那么它将起作用.在此帖子中说终端规则定义的eariler将遮盖以后定义的规则.但是,如果我在语法中重新定义terminal ID
,无论将其放在terminal HEX
的前面还是后面,antlr都会表示The following token definitions can never be matched because prior tokens match the same input: RULE_HEX,RULE_MYBOOLEAN
. k=0x00b
中也会发生此问题. k=0xaab
有效,但k=0x00b
无效.
but a=4
won't be a valid RelationCompare
because a
and 4
will be treat as HEX
s. I found this because if I change the relation to j=44
then it works. In this post it said terminal rule defined eariler will shadow those defined later. However, if I redefine terminal ID
in my grammar, whether put it in front or after of terminal HEX
, antlr will conplain The following token definitions can never be matched because prior tokens match the same input: RULE_HEX,RULE_MYBOOLEAN
. This problem happens in k=0x00b
as well. k=0xaab
is valid but k=0x00b
is not.
有什么建议吗?
推荐答案
稍后,我找到了想要的原始antlr语法,因此我只是将antlr语法转换为xtext语法.这是我定义这些基本类型的方法:
Later I found the original antlr grammar for what I want to do therefore I simply translate the antlr grammar to xtext grammar. Here is how I defining those basic types:
terminal fragment A: 'a'|'A';
...
terminal fragment Z: 'z'|'Z';
terminal fragment DIGIT: '0'..'9';
terminal fragment LETTER: ('a'..'z'|'A'..'Z');
terminal fragment HEX: ('a'..'f'|'A'..'F'|'0'..'9');
terminal fragment EXPONENT: E ('+'|'-')? DIGIT+;
terminal INTEGER returns ecore::EInt: '-'? DIGIT+;
terminal FLOAT returns ecore::EFloat: INTEGER EXPONENT | INTEGER '.' DIGIT* EXPONENT?;
terminal BOOLEAN: T R U E | F A L S E;
原始语法中的日期规则被视为字符串.
The Date rule in original grammar is treated as a string.
关于规则名称(规则:Antlr语法=> xtext语法)
About rules name (Rules: Antlr Grammar => xtext Grammar)
- 解析器规则:以小写字母开头=>以大写字母开头的规则(每个都是Java类)
- 终端规则:以大写字母=>开头,并使用所有带有
terminal
前缀的大写字母 - 片段终端规则:
fragment
ID =>terminal fragment
ID
- parser rule: starting with lowercase => rules starting with uppercase (each will be a Java Class)
- terminal rule: starting with uppercase => using all uppercase with
terminal
prefix - fragment terminal rule:
fragment
ID =>terminal fragment
ID
在antlr中,这样定义参数列表:
In antlr a list of arguments is defined like this:
functionArgs
: '(' ')'
| '(' t1=term ( ',' tn=term )* ')'
;
相应的xtext语法为:
The corresponding xtext grammar is:
FunctionArgs
: '(' ')'
| '(' ts+=Term (',' ts+=Term )* ')'
;
对于带有[
]
properties[PropertyDefinitions props]
: property[props] (K_AND property[props])*
;
大多数情况下,它们可以移动到左侧
Most of the time they could be moved to the left hand side
Properties
: props+=Property (K_AND props+=Property)*
;
现在它可以正常工作了.
Now it's working as expected.
这篇关于xtext中的终端/数据类型/解析器规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!