为什么我的一些令牌无法识别?



>我正在尝试构建一个简单的HTML词法分析器,我像这样定义我的令牌:

tokens = [
'text',
'num',
'id',
'url',
'newline',
'space',
'bigger',
'sp',
'del',
'vert',
'carr',
]
reserved = {'<html lang = "en"':"html_open", '<h1': 'h1_open', '</h1>':'h1_close','<p': 'p_open',
'</p': 'p_close', '<body': 'body_open', 'id=': 'id_att', '</body': 'body_close' }
tokens = tokens+list(reserved.values())
t_bigger = '>'
t_newline = r'[n]'
t_sp = r'[s]'
t_del = r'[d]'
t_vert = r'[v]'
t_carr = r'[r]'
def t_text(t):
r'[a-zA-Z_0-9_<_ _"_=_/][ a-zA-Z_0-9_<_ _"_=_/]*'
t.type = reserved.get(t.value,'text')    
return t
def t_id(t):
r'[a-zA-Z_0-9_<_"][a-zA-Z_0-9_"]*'
t.type = reserved.get(t.value,'id')
return t
def t_num(t):
r'd'
t.value = int(t.value)
return t
def t_error(t):
print ("invalid char '%s'" %t.value[0])
t.lexer.skip(1)

我用来测试的文本是:

<html lang = "en">
<body> 
<h1 id="someid"> This is a test </h1> 
<p> Paragraph </p> 
</body>

当我运行它时,我得到这个:

LexToken(html_open,'<html lang = "en"',1,0)
LexToken(bigger,'>',1,17)
LexToken(sp,'r',1,18)
LexToken(newline,'n',1,19)
LexToken(body_open,'<body',1,20)
LexToken(bigger,'>',1,25)
LexToken(text,' ',1,26)
LexToken(sp,'r',1,27)
LexToken(newline,'n',1,28)
LexToken(sp,'t',1,29)
LexToken(text,'<h1 id="someid"',1,30)
LexToken(bigger,'>',1,45)
LexToken(text,' This is a test </h1',1,46)
LexToken(bigger,'>',1,66)
LexToken(text,' ',1,67)
LexToken(sp,'r',1,68)
LexToken(newline,'n',1,69)
LexToken(sp,'t',1,70)
LexToken(p_open,'<p',1,71)
LexToken(bigger,'>',1,73)
LexToken(text,' Paragraph </p',1,74)
LexToken(bigger,'>',1,88)
LexToken(text,' ',1,89)
LexToken(sp,'r',1,90)
LexToken(newline,'n',1,91)
LexToken(body_close,'</body',1,92)
LexToken(bigger,'>',1,98)

我的问题是<h1 id="someid"被解释为"文本",并且

LexToken(h1_open,'<h1)
LexToken(id_att, 'id=')
LexToken(id, ' "someid" ')
LexToken(text,' Paragraph')
LexToken(p_close,'</p')

我怎样才能做到这一点?我已经将h1_open、p_close和id_att定义为"保留",认为它们将被单独识别,就像p_open和body_open的工作方式一样。我不明白为什么它与其他令牌的工作方式不同。

您所做的一切都被添加到<h1作为reserved的关键。这不会使字符串变得特别。它也不会更改包含<h1的字符串与正则表达式的匹配方式。<h1 id="someid"与您的文本模式匹配,因此词法分析器执行t_text操作函数。

总的来说,这不是进行词法分析的方法。词法分析应将输入划分为词素,其中每个词素都是基元。<h1 id="someid"不是词法;它可能是五个词素(<h1id="someid",假设空格已被丢弃(。输入的结构将由解析器进行分析,并且无需为了节省一两个生产而使词法分析器复杂化。

HTML 解析通常要求您使用不同的词法状态来处理标签之外的文本以及构成标签的结构化程度更高的文本。您可能会发现词法状态很有帮助。

最新更新