将词汇元素分解成碎片

时间:2015-01-03 01:34:19

标签: grako

我的语法文件test.ebnf看起来像,

start = identifier ;

identifier =
  /[a-z]*/ rest;

rest = /[0-9]*/ ;

当我在输入“test1234”中运行这个语法时,我希望它将“test1234”作为单个lexeme,但是AST看起来像,

AST:
['test', '1234']

我尝试将nameguard功能设置为false而没有运气。如何在不编写identifier = /[a-z]*[0-9]*/等规则的情况下获得此行为?

1 个答案:

答案 0 :(得分:1)

Grako 将始终返回一个列表,其中每个元素在规则的右侧都有一个对象,除非只有一个元素。即使在命名元素时,具有相同名称的多个匹配也将返回一个列表。只是连接元素是不合理的,因为它们的AST可能是项目所需的复杂对象。

在您的情况下,您可以使用语义操作来加入identifier部分:

def identifier(self, ast):
    return ''.join(ast)

或者重新定义identifier规则以包含单个元素:

identifier
    =
    /[a-z]+[0-9]*|[a-z]*[0-9]+/
    ;

(注意正则表达式的更改,因此它永远不会匹配空字符串)。