PLY Lex:ID 可以是任何东西
PLY Lex: ID could be anything
我有以下简单格式:
BLOCK ID {
SUBBLOCK ID {
SUBSUBBLOCK ID {
SOME STATEMENTS;
};
};
};
我将 ply 配置为使用这种格式。但问题是 ID 可以是任何字符串,包括“BLOCK”、“SUBBLOCK”等。
在词法分析器中,我将 ID 定义为:
@TOKEN(r'[a-zA-Z_][a-zA-Z_0-9]*')
def t_ID(self, t):
t.type = self.keyword_map.get(t.value, "ID")
return t
但这意味着 BLOCK 字将不允许作为块名称。
我该如何解决这个问题?
我可能不明白你的问题
但我认为像下面这样的东西会起作用(已经很长时间了
我搞砸了 PLY 所以请记住这是伪代码
FUNCTION_ARGS = zeroOrMore(lazy('STATEMENT'),sep=',')
FUNCTION_CALL = t_ID + lparen + FUNCTION_ARGS + rparen
STATEMENT= FUNCTION_CALL | t_Literal | t_ID
SUBBLOCK = Literal('SUBBLOCK') + t_ID + lbrace + STATEMENT + rbrace
BLOCK = Literal('BLOCK') + lbrace + oneOrMore(SUBBLOCK) + rbrace
最简单的解决方案是创建一个 non-terminal name
来代替 ID
在需要名称的作品中使用,例如 block : BLOCK name braced_statements
:
# Docstring is added later
def p_name(self, p):
p[0] = p[1]
然后计算 name
的产生式,并通过在生成解析器之前执行此操作将它们分配给 p_name
的文档字符串:
Parser.p_name.__doc__ = '\n| '.join(
['name : ID']
+ list(Lexer.keyword_map.values())
)
我有以下简单格式:
BLOCK ID {
SUBBLOCK ID {
SUBSUBBLOCK ID {
SOME STATEMENTS;
};
};
};
我将 ply 配置为使用这种格式。但问题是 ID 可以是任何字符串,包括“BLOCK”、“SUBBLOCK”等。 在词法分析器中,我将 ID 定义为:
@TOKEN(r'[a-zA-Z_][a-zA-Z_0-9]*')
def t_ID(self, t):
t.type = self.keyword_map.get(t.value, "ID")
return t
但这意味着 BLOCK 字将不允许作为块名称。
我该如何解决这个问题?
我可能不明白你的问题
但我认为像下面这样的东西会起作用(已经很长时间了 我搞砸了 PLY 所以请记住这是伪代码
FUNCTION_ARGS = zeroOrMore(lazy('STATEMENT'),sep=',')
FUNCTION_CALL = t_ID + lparen + FUNCTION_ARGS + rparen
STATEMENT= FUNCTION_CALL | t_Literal | t_ID
SUBBLOCK = Literal('SUBBLOCK') + t_ID + lbrace + STATEMENT + rbrace
BLOCK = Literal('BLOCK') + lbrace + oneOrMore(SUBBLOCK) + rbrace
最简单的解决方案是创建一个 non-terminal name
来代替 ID
在需要名称的作品中使用,例如 block : BLOCK name braced_statements
:
# Docstring is added later
def p_name(self, p):
p[0] = p[1]
然后计算 name
的产生式,并通过在生成解析器之前执行此操作将它们分配给 p_name
的文档字符串:
Parser.p_name.__doc__ = '\n| '.join(
['name : ID']
+ list(Lexer.keyword_map.values())
)