xtext 中的终端/数据类型/解析器规则 [英] terminal/datatype/parser rules in xtext

查看:28
本文介绍了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 rule SIGNINT: '-'? 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 可以匹配输入,例如RULE_INT '-' RULE_INT '-' RULE_INT",使用多种选择:2, 3结果,该输入禁用了替代方案 3

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 因为 a4 将被视为HEXs.我发现这是因为如果我改变与 j=44 的关系,那么它就可以工作了.在这个帖子中,它说较早定义的终端规则将影响稍后定义的规则.但是,如果我在语法中重新定义terminal ID,无论是放在terminal HEX 的前面还是后面,antlr 都会提示以下标记定义永远无法匹配因为先前的标记匹配相同的输入: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 HEXs. 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 Grammar => xtext Grammar)

About rules name (Rules: Antlr Grammar => xtext Grammar)

  • 解析器规则:以小写开头 => 以大写开头的规则(每个都是一个 Java 类)
  • 终端规则:以大写开头 => 使用带有 terminal 前缀的所有大写
  • 片段终端规则:fragment ID => 终端片段 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)*
;

现在它按预期工作.

这篇关于xtext 中的终端/数据类型/解析器规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆