Parsing 确定令牌是否是行上的第一个令牌
我正在为自定义编程语言编写lexer。首先,我想说这是一个个人练习,我想用手写的方式来做,不要使用任何生成器工具,如Lex或Flex 在我的语言中,语法之一是有三种类型的注释:单行注释、多行注释和文档注释:Parsing 确定令牌是否是行上的第一个令牌,parsing,compiler-construction,tokenize,Parsing,Compiler Construction,Tokenize,我正在为自定义编程语言编写lexer。首先,我想说这是一个个人练习,我想用手写的方式来做,不要使用任何生成器工具,如Lex或Flex 在我的语言中,语法之一是有三种类型的注释:单行注释、多行注释和文档注释: 单行注释: code(x, y, z); %% a comment that ends at the end of the line moreCode(x, y, z); code(x, %- a comment that starts and ends on the same line.
code(x, y, z); %% a comment that ends at the end of the line
moreCode(x, y, z);
code(x, %- a comment that starts and ends on the same line. -% y, z);
moreCode(x, %- a comment that starts, contains a line break,
and then ends. -% y, z);
code(x, y, z); %% a comment that ends at the end of the line
moreCode(x, y, z);
code(x, %- a comment that starts and ends on the same line. -% y, z);
moreCode(x, %- a comment that starts, contains a line break,
and then ends. -% y, z);
%%%
a doc comment. the delimiters must be on their own line
%%%
code(x, y, z);
code
-标识符(
-符号)
-符号代码>-符号
%%%此文本
评论
输出%%代码>-注释
notCommentedOut
-标识符(
-符号)
-符号代码>-符号
%%
都被视为单行注释(因为它以%%
开头)。
这意味着正确的标记化应该是:
code
-标识符(
-符号)
-符号代码>-符号
%%%这已被注释掉。
-注释notCommentedOut
-标识符(
-符号)
-符号代码>-符号
“也”
-字符串+
-符号代码>-符号
注释输出
-标识符代码>-符号
%%%也注释掉了
-注释# this is a heading
foobar # this is not a heading
```
this is a fenced code block
```
foobar ``` this is not
a fenced code block ```
在LaTeX中,我们可以将块方程:
$$
f(x) = 2^{x + 1}
$$
我的方法
代码
(为清晰起见,请键入脚本并缩小。)
//提高扫描仪的`n`字符数
函数前进(n:number=1):无效{
如果(n==1){
//将c0重新指定给下一个字符
//将c1重新分配给前瞻(1)
//将指挥控制重新分配给前瞻(2)
}否则{
预付款(n-1)
预付款
}
}
而(!character.done){
if(空白。包括(c0)){
const wstoken=新标记(character.value)
wstoken.type=TokenType.WHITESPACE
预付款
while(!character.done&&whitespace.includes(c0)){
wstoken.cargo+=c0
预付款
}
//仅当我们希望lexer返回空白时,才产生wstoken//
打破
}
常量标记=新标记(character.value)
如果(c0==结束标记){
token.type=TokenType.EOF
预付款
}如果(c0+c1+c2==comment\u doc\u start){//我们找到了一个doc注释:`%%%`
token.type=TokenType.COMMENT
token.cargo+=注释\单据\开始
预付款(备注\单据\起始长度)
而(!character.done&&c0+c1+c2!==comment\u doc\u end){
如果(c0==ENDMARK)抛出新错误(“在注释结尾之前找到文件结尾”)
token.cargo+=c0
预付款
}
//将注释\文档\结尾添加到令牌
token.cargo+=注释\单据\结束
预付款(备注\单据\结束长度)
}如果(c0+c1==注释\u多行\u开始){//我们找到了一个多行注释:`%-%`
token.type=TokenType.COMMENT
token.cargo+=注释\u多\u开始
前进(注释\u多\u开始长度)
而(!character.done&&c0+c1!==注释\u多\u结束){
如果(c0==ENDMARK)抛出新错误(“在注释结尾之前找到文件结尾”)
token.cargo+=c0
预付款
}
//向令牌添加注释\u多\u结尾
token.cargo+=注释\u多\u结束
进阶(注释\u多个\u结束。长度)
}如果(c0+c1===注释行){//我们找到了一行注释:`%%`
token.type=TokenType.COMMENT
token.cargo+=注释行
预付款(注释行长度)
而(!character.done&&c0!='\n'){
如果(c0==ENDMARK)抛出新错误(“在注释结尾之前找到文件结尾”)
token.cargo+=c0
预付款
}
//不要将“\n”添加到令牌
}否则{
抛出新错误(`I发现一个我无法识别的字符或符号:${c0}`)
}
收益券
}
思维过程
我认为有两种选择,这两种都不可取
一个选项是在while
循环之外有一个全局变量,一个布尔标志,指示上一个标记是否为空白并包含\n
。然后使用该标志通知下一个标记,该标记以%%
开头。如果该标志为true,则注释应在下一个%%处关闭;否则它应该在下一次\n
时关闭。我不确定我是否喜欢这个选项,因为它涉及到为每个代码标记设置标志。它也不考虑结尾分隔符,它也必须在自己的行上
另一个选择是回溯。当lexer到达一个以%%%
开头的令牌时,请检查上一个令牌是否为空白并且包含\n
。如果是这样,则%%%%
标记是一个文档注释,应该在下一次%%
时关闭。如果不是,则为内联注释,