首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何编写textx语法规则来检测标准数据类型而不修改它们?

如何编写textx语法规则来检测标准数据类型而不修改它们?
EN

Stack Overflow用户
提问于 2019-04-26 07:32:48
回答 1查看 262关注 0票数 0

我想要编写一个textx语法规则,它可以由另一个已定义的规则或任何类型的标准数据类型(Int、Float、String等)组成。

这适用于一个简单的textx DSL,它应该包括编写(并最终翻译)条件,这些条件可以由其他语法规则(如预定义函数)或任何类型的标准预定义数据类型(String/Int/Float/Bool/ID)组成。

所以,我实际上希望能够写一些类似的东西

代码语言:javascript
复制
condition insert input data 5 equal 10 BEGIN
    ...
END

这代表了正常的如果。insert input data 5是一个规则,稍后将其转换为普通函数调用insertOutputData(5)。我在这里使用的语法:

代码语言:javascript
复制
Model: commands*=Command;
Command: Function | Branch;
Function: Func_InsertInputData | Func_InsertOutputData;
Func_InsertInputData: 'insert input data' index=INT;
Func_InsertOutputData: 'insert output data' index=INT;
Branch: 'condition' condition=Condition 'BEGIN'
    commands*=Command;
'END'
Condition: Cond_Equal | Cond_And | Cond_False;
Cond_Equal: op1=Operand 'equal' op2=Operand;
Cond_And: op1=Operand 'and' op2=Operand;
Cond_False: op1=Operand 'is false';
Operand: Function | OR_ANY_OTHER_KIND_OF_DATA;

在解释器中,我试图通过以下操作读取代码:

代码语言:javascript
复制
def translateCommands(cmds):
    commands = []
    for cmd in cmds:
        commands.append(translateCommand(cmd))
    return commands

def translateCommand(cmd):
    print(cmd)
    print(cmd.__class__)
    if cmd.__class__.__name__ == 'int' or cmd.__class__.__name__ == 'float':
        return str(cmd)
    elif cmd.__class__.__name__ == 'str':
        return '\'' + cmd + '\''
    elif(cmd.__class__.__name__ == 'Branch'):
        s = ''
        if(cmd.condition.__class__.__name__ ==  'Cond_Equal'):
            s = 'if ' + translateCommand(cmd.condition.op1) + '==' + translateCommand(cmd.condition.op2) + ':'
        if(cmd.condition.__class__.__name__ == 'Cond_And'):
            s = 'if ' + translateCommand(cmd.condition.op1) + 'and' + translateCommand(cmd.condition.op2) + ':'
        # ...
        commandsInBlock = translateCommands(cmd.commands)
        for command in commandsInBlock:
            s += '\n    '+command
        return s

OR ANY OTHER KIND OF DATA,我尝试了列出实际的数据类型,但这是行不通的。如果我用上面用Function | FLOAT | INT | BOOL | ID | STRING作为操作数规则的DSL代码处理模型,则整数(示例中等于后的10 )被转换为浮动。

代码语言:javascript
复制
if insertInputData(5)==10.0:

如果我使用操作数规则(如Function | INT | FLOAT | BOOL | ID | STRING )处理模型,则会得到一个错误

代码语言:javascript
复制
textx.exceptions.TextXSyntaxError: None:13:43: error: Expected 'BEGIN' at position (13, 43) => 't equal 10*.0 BEGIN  '.

我希望看到的结果是

代码语言:javascript
复制
if insertInputData(5)==10:

代码语言:javascript
复制
if insertInputData(5)==10.0:

使用

代码语言:javascript
复制
condition insert input data 5 equal 10.0 BEGIN
    ...
END

但是textx似乎总是尝试将它在那个位置得到的值转换为操作数规则中的建议类型,在这种情况下,这种类型是不好的。如何修改我的规则,以便它能够在不修改任何内容的情况下正确地检测每一种数据类型?

编辑1

Igorć刚刚描述了这个问题,我遵循了他给出的方法。

语法(相关部分):

代码语言:javascript
复制
Command: Function | Branch | MyNumber;
#...
Oparand: Function | MyNumber | BOOL | ID | STRING;
MyNumber: STRICTFLOAT | INT;
STRICTFLOAT: /[+-]?(((\d+\.(\d*)?|\.\d+)([eE][+-]?\d+)?)|((\d+)([eE][+-]?\d+)))(?<=[\w\.])(?![\w\.])/;

代码:

代码语言:javascript
复制
mm = metamodel_from_str(grammar)
mm.register_obj_processors({'STRICTFLOAT': lambda x: float(x)})

dsl_code = '''
10
10.5
'''
model = mm.model_from_str(dsl_code)
commands = iterateThroughCommands(model.commands)

这会导致

代码语言:javascript
复制
10
<class 'int'>

'10.5'
<class 'str'>

所以,没有什么东西可以让对象处理器工作.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-26 09:42:08

问题是,每个有效整数都可以被解释为FLOAT,因此,如果您将规则排序为FLOAT | INT |...,则会得到float类型,因为FLOAT规则将与之匹配,但如果将规则定购为INT | FLOAT|...,则解析器将消耗该数字的一部分,直到.和than解析不再继续。

在textX的开发版本(请参阅CHANGELOG.md)中,这是通过引入永远不匹配整数的STRICTFLOAT规则来解决的,并且内置的NUMBER规则被更改为首先尝试匹配STRICTFLOAT,然后是INT

下一个版本将是2.0.0,我希望它将在未来几周内发布。同时,您可以直接从github安装,也可以修改语法,使其具有如下内容:

代码语言:javascript
复制
MyNumber: STRICTFLOAT | INT;
STRICTFLOAT: /[+-]?(((\d+\.(\d*)?|\.\d+)([eE][+-]?\d+)?)|((\d+)([eE][+-]?\d+)))(?<=[\w\.])(?![\w\.])/;   // or the float format you prefer

并将对象处理器注册为将转换为PythonfloatSTRICTFLOAT类型。升级到textX 2.0.0之后,您应该将对MyNumber的引用替换为语法中的NUMBER

更多信息可以在报告的问题中找到。

编辑1:

由于报告的这里错误,建议的解决方案目前无法工作。

编辑2:

该bug在开发版本中得到了修复。在2.0.0发布之前,您必须

代码语言:javascript
复制
pip install https://github.com/textX/textX/archive/master.zip

如果不想更改默认类型,则根本不需要解决方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55862851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档