Ply 是可能的,但需要一些数据按摩和令牌构建。
import re
from ply import lex
tokens = ('LOOP','ASSIGNMENT')
literals = '=,'
re_float = r'(\d+\.\d+)'
re_int = r'(\d+)'
re_ident = r'([A-Za-z]\w*)'
re_expr = '(%s)' % '|'.join([re_float, re_int, re_ident])
re_loop = 'DO%s%s=%s,%s' % (re_int, re_ident, re_expr, re_expr)
@lex.TOKEN(re_loop)
def t_LOOP(t):
return t
re_assignment = '%s=%s' % (re_ident, re_expr)
@lex.TOKEN(re_assignment)
def t_ASSIGNMENT(t):
return t
def t_newline(t):
r'\n+'
t.lineno += len(t.value) # count newlines
def t_error(t):
print "syntax error at %s, line# %d" % (t.value, t.lineno)
DATA = """-- Spaces are ignored in FORTRAN
DO 5 I=1,10 -- Loop
DO 5 I=1.10 -- Assignment (DO5I = 1.10)"""
def preprocess(data):
re_spaces=re.compile('\s*')
re_comment=re.compile('--.*$')
lines = []
for line in data.split('\n'): # split into lines
line = re_spaces.sub('', line)
line = re_comment.sub('', line)
if not line: continue # skip blank lines
line = line.upper()
lines.append(line)
return '\n'.join(lines)+'\n'
print re_assignment
lexer = lex.lex()
lexer.input(preprocess(DATA))
while True:
tok = lexer.token()
if not tok: break
print tok
首先,您必须手动去除注释、空格并强制为大写。然后你构建一个解析器,它基本上实现了你的内联语法。我认为它最终会变得无法管理。如果是我,我认为实现我自己的词法分析器会容易得多,它只进行逐行正则表达式匹配。Ply 的词法分析器真正做的就是用你所有的小正则表达式构建一个巨大的正则表达式,然后逐步匹配标记。