我正在尝试为使用关键字对(以空格分隔)的文件类型编写解析器,并且正在努力使用正确的方法来做到这一点。令牌的一些示例可能是:
angle spring
angle dampen
angle collision
还有块定义和以该块结尾的令牌,例如:
dynamics
angle spring 1.0
angle dampen 0.0
angle collision 0.0
some 1 2 3
more ['stuff' 'here']
tokens "values can be strings, paths, etc"
end dynamics
换行符似乎很重要,我一直在用它来确定我要查看的是关键字还是仅仅是常规的旧字符串(关键字应是每行的第一个标记)。我是否采用正确的方法?我是否应该只在yacc阶段对所有内容进行标记并更严格地定义对?
谢谢你的时间!
问题是您试图将逻辑上单个标记视为多个标记。如果关键字包含空格,则表示空格是关键字标记的一部分。
如果定义关键字标记(包括空格),则在解析器中将不再需要处理它们。这意味着您应该将关键字匹配与常规标识符匹配分开。
例如:
from ply.lex import TOKEN
KEYWORDS = [
r'some', r'keyword',
r'keyword with token',
r'other keyword',
]
keyword = '|'.join(keyword.replace(' ', '\s+') for keyword in KEYWORDS)
@TOKEN(keyword)
def t_KEYWORD(t):
# remove spaces
value = ''.join(x for x in t.value if not x.isspace())
return value.upper()
请注意以下@TOKEN(keyword)
行:您可以使用TOKEN
装饰器动态设置函数的文档字符串。这允许将复杂的正则表达式用于定义标记,即使使用表达式而不是简单的字符串文字来“定义”定义它们也是如此。
另一种方法是将以空格分隔的关键字视为多个关键字。因此,您保留了标识符和关键字的常规定义,并修改了语法以使用多个关键字而不是一个。
例如,您将具有如下语法规则:
def p_dynamics(p):
'DYNAMICS BLOCK END DYNAMICS'
代替:
def p_dynamics(p):
'DYNAMICS BLOCK END_DYNAMICS'
根据约束条件,您可能会更容易实现一种解决方案。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句