Aar*_*ken 3 parsing lex go lexer flex-lexer
我有兴趣在我的flex文件中添加分号插入ala Google Go.
来自Go文档:
分号
与C一样,Go的正式语法使用分号来终止语句; 与C不同,这些分号不会出现在源代码中.相反,词法分析器使用一个简单的规则在扫描时自动插入分号,因此输入文本大多没有分号.
规则是这样的.如果换行符之前的最后一个标记是一个标识符(包括int和float64之类的单词),则是一个基本文字,例如数字或字符串常量,或者其中一个标记
Run Code Online (Sandbox Code Playgroud)break continue fallthrough return ++ -- ) }词法分析器总是在令牌后插入分号.这可以概括为"如果新行出现在可以结束语句的标记之后,则插入分号".
在结束括号之前也可以省略分号,所以语句如
Run Code Online (Sandbox Code Playgroud)go func() { for { dst <- <-src } }()不需要分号.Idiomatic Go程序仅在诸如for循环子句之类的地方使用分号,以分隔初始化程序,条件和继续元素.如果您以这种方式编写代码,它们也是分隔行上多个语句所必需的.
一个警告.你永远不应该把控制结构的开括号(if,for,switch或select)放在下一行.如果这样做,将在大括号之前插入分号,这可能会导致不良影响.写这样的
Run Code Online (Sandbox Code Playgroud)if i < f() { g() }不喜欢这个
Run Code Online (Sandbox Code Playgroud)if i < f() // wrong! { // wrong! g() // wrong! } // wrong!
我将如何进行此操作(如何在流中插入令牌,如何查看匹配的最后一个令牌以查看它是否是一个好主意等等)?
我也在使用野牛,但Go似乎只是用他们的词法分析器插入分号.
您可以通过在必要时插入分号的函数传递lexer结果标记.在检测到需要插入时,可以将下一个令牌放回输入流,基本上在下一轮中再次使用它.
下面是一个在换行符之前插入SEMICOLON的示例,当它跟随WORD时.野牛文件"insert.y"是这样的:
%{
#include <stdio.h>
void yyerror(const char *str) {
printf("ERROR: %s\n", str);
}
int main() {
yyparse();
return 0;
}
%}
%union {
char *string;
}
%token <string> WORD
%token SEMICOLON NEWLINE
%%
input:
| input WORD {printf("WORD: %s\n", $2); free($2);}
| input SEMICOLON {printf("SEMICOLON\n");}
;
%%
Run Code Online (Sandbox Code Playgroud)
而lexer是由flex生成的:
%{
#include <string.h>
#include "insert.tab.h"
int f(int token);
%}
%option noyywrap
%%
[ \t] ;
[^ \t\n;]+ {yylval.string = strdup(yytext); return f(WORD);}
; {return f(SEMICOLON);}
\n {int token = f(NEWLINE); if (token != NEWLINE) return token;}
%%
int insert = 0;
int f(int token) {
if (insert && token == NEWLINE) {
unput('\n');
insert = 0;
return SEMICOLON;
} else {
insert = token == WORD;
return token;
}
}
Run Code Online (Sandbox Code Playgroud)
用于输入
abc def
ghi
jkl;
Run Code Online (Sandbox Code Playgroud)
它打印
WORD: abc
WORD: def
SEMICOLON
WORD: ghi
SEMICOLON
WORD: jkl
SEMICOLON
Run Code Online (Sandbox Code Playgroud)
输出非常量令牌需要一些额外的工作 - 我试图保持这个例子简单,只是为了给出这个想法.