我正在写一种类似玉的语言,可以转换为html。标签定义如下:
section #mainWrapper .container
此代码将转换为:
<section id="mainWrapper" class="container">
词法分析器应该区分类和id还是只吐出带有名称的特殊字符?
换句话说,令牌数组应如下所示:
[
{type: 'tag', value: 'section'},
{type: 'id', value: 'mainWrapper'},
{type: 'class', value: 'container'}
]
然后解析器将它们组装成树
还是词法分析器应该是非常原始的并且仅返回匹配的字符串,然后解析器负责区分它们?:
[
{type: 'name', value: 'section'},
{type: 'name', value: '#mainWrapper'},
{type: 'name', value: '.container'}
]
答案 0 :(得分:1)
根据经验,令牌解析器不应解析,而解析器不应令牌化。
在这种具体情况下,在我看来,像section
这样的类似名称的标记的任何未经修饰的使用都不一定一定是tag
。 section
更有可能是一个标记,因为它的语法上下文。如果令牌发布者尝试将其标记为tag
,则令牌发布者正在跟踪语法上下文,这意味着它正在解析。
信号.
和#
不太清晰。您可以将它们视为单字符标记(语法将坚持使用名称),或者可以将它们视为特殊字符串类型的第一个字符。有些事情可能会以一种或另一种方式影响您:
可以使用空格将符号与以下名称分隔吗? (# mainWrapper
)。如果是这样,则该印记可能是令牌。
类或id的词法形式与名称不同吗?例如,考虑使用特殊字符。如果您不知道对象之前没有任何标记,就无法准确识别该对象,那么最好将其视为单个标记。
还有其他表示class
名称的方法。例如,您如何表示多个类?我脑海中浮现出一些可能性:
#classA #classB
#(classA classB)
#"classA classB"
class = "classA classB"
如果第一个选项以外的任何其他选项均有效,则可能应该将#
设为令牌。但是正确处理带引号的字符串可能会带来其他挑战。特别是,它可能需要重新标记字符串文字的内容,这违反了解析器不应标记化的启发式方法。幸运的是,这些不是绝对的规则。有时需要重新标记。但是请尽量减少。
将词汇和句法分析分开不应成为束手无策。这是一种代码组织技术,旨在使各个部分更易于编写,理解,调试和记录。经常(但并非总是)这种分隔使您的语言用户更容易理解语法,这也很重要。但这并不适合每个解析任务,并且精确的边界是灵活的(但不是多孔的:您可以将边界放在最方便的位置,但是一旦放置,就不要试图通过裂缝推动事物了。)>
如果您发现这样的关注点分离对您的项目来说太困难了,您应该重新考虑您的语言设计或尝试进行无扫描仪的解析。