jjzjj

parsing - 分号插入 ala google go with flex

coder 2023-06-27 原文

我有兴趣在我的 flex 文件中添加 Google Go 中的分号插入。

来自 Go 文档:

Semicolons

Like C, Go's formal grammar uses semicolons to terminate statements; unlike C, those semicolons do not appear in the source. Instead the lexer uses a simple rule to insert semicolons automatically as it scans, so the input text is mostly free of them.

The rule is this. If the last token before a newline is an identifier (which includes words like int and float64), a basic literal such as a number or string constant, or one of the tokens

break continue fallthrough return ++ -- ) }

the lexer always inserts a semicolon after the token. This could be summarized as, “if the newline comes after a token that could end a statement, insert a semicolon”.

A semicolon can also be omitted immediately before a closing brace, so a statement such as

go func() { for { dst <- <-src } }()

needs no semicolons. Idiomatic Go programs have semicolons only in places such as for loop clauses, to separate the initializer, condition, and continuation elements. They are also necessary to separate multiple statements on a line, should you write code that way.

One caveat. You should never put the opening brace of a control structure (if, for, switch, or select) on the next line. If you do, a semicolon will be inserted before the brace, which could cause unwanted effects. Write them like this

if i < f() {
    g()
}

not like this

if i < f()  // wrong! 
{           // wrong!
    g()     // wrong!
}           // wrong!

我将如何着手执行此操作(如何在流中插入标记,如何查看匹配的最后一个标记以查看它是否是个好主意,等等)?

我也在使用 bison,但 Go 似乎只使用他们的词法分析器来插入分号。

最佳答案

您可以通过在必要时插入分号的函数传递词法分析器结果标记。在检测到需要插入时,可以将下一个标记放回输入流,基本上在下一轮再次对它进行词法分析。

下面是一个在换行符之前插入分号的示例,当它跟在 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");}
     ;
%%

词法分析器由 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;
  }
}

用于输入

abc def
ghi
jkl;

它打印

WORD: abc
WORD: def
SEMICOLON
WORD: ghi
SEMICOLON
WORD: jkl
SEMICOLON

Unput 一个非常量标记需要一些额外的工作 - 我尽量让示例保持简单,只是为了给出想法。

关于parsing - 分号插入 ala google go with flex,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10826744/

有关parsing - 分号插入 ala google go with flex的更多相关文章

  1. ruby parslet : parsing multiple lines - 2

    我正在寻找一种匹配多行Parslet的方法。代码如下所示:rule(:line){(match('$').absent?>>any).repeat>>match('$')}rule(:lines){line.repeat}但是,lines将始终以无限循环结束,这是因为match('$')将无休止地重复以匹配字符串的结尾。是否可以匹配可以为空的多行?irb(main)>lines.parse($stdin.read)Thisisamultilinestring^D应该匹配成功。我错过了什么吗?我还尝试了(match('$').absent?>>any.maybe).repeat(1)>>

  2. ruby - 如何在 Ruby 字符串中插入项目符号字符? - 2

    我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195

  3. ruby - 允许主机名包含下划线的 URI.parse 的替代方法 - 2

    我正在使用DMOZ的listofurltopics,其中包含一些具有包含下划线的主机名的url。例如:608609TheOuterHeaven610InformationandimagegalleryofMcFarlane'sactionfiguresforTrigun,Akira,TenchiMuyoandotherJapaneseSci-Fianimations.611Top/Arts/Animation/Anime/Collectibles/Models_and_Figures/Action_Figures612虽然此url可以在网络浏览器中使用(或者至少在我的浏览器中可以使用:

  4. ruby - 在 ruby​​ 中使用自动创建插入数组 - 2

    我想知道是否可以通过自动创建数组来插入数组,如果数组不存在的话,就像在PHP中一样:$toto[]='titi';如果尚未定义$toto,它将创建数组并将“titi”压入。如果已经存在,它只会推送。在Ruby中我必须这样做:toto||=[]toto.push('titi')可以一行完成吗?因为如果我有一个循环,它会测试“||=”,除了第一次:Person.all.eachdo|person|toto||=[]#with1billionofperson,thislineisuseless999999999times...toto.push(person.name)你有更好的解决方案吗?

  5. ruby-on-rails - 在方法调用中插入 Ruby? - 2

    在我的用户模型中,我有一堆属性,例如is_foos_admin和is_bars_admin,它们决定允许用户编辑哪些类型的记录。我想干掉我的编辑链接,目前看起来像这样:'edit'ifcurrent_user.is_foos_admin?%>...'edit'ifcurrent_user.is_bars_admin?%>我想做一个帮助程序,让我传入一个foo或bar并返回一个链接来编辑它,就像这样:助手可能看起来像这样(这不起作用):defedit_link_for(thing)ifcurrent_user.is_things_admin?link_to'Edit',edit_poly

  6. Ruby 将对象插入现有的已排序对象数组 - 2

    我有以下现有的Dog对象数组,它们按age属性排序:classDogattr_accessor:agedefinitialize(age)@age=ageendenddogs=[Dog.new(1),Dog.new(4),Dog.new(10)]我现在想插入一条新的狗记录,并将它放在数组中的正确位置。假设我想插入这个对象:another_dog=Dog.new(8)我想把它插入到数组中,让它成为数组中的第三项。这是一个人为的示例,旨在演示我特别想如何将一个项目插入到现有的有序数组中。我意识到我可以创建一个全新的数组并重新对所有对象进行排序,但这不是我的目标。谢谢!

  7. Ruby:如何将条件插入字符串连接 - 2

    在字符串连接中,是否可以直接在语句中包含条件?在下面的示例中,我希望仅当dear列表不为空时才连接"mydear"。dear=""string="hello"+"mydear"unlessdear.empty?+",goodmorning!"但是结果报错:undefinedmethod'+'fortrue我知道另一种方法是在这条语句之前定义一个额外的变量,但我想避免这种情况。 最佳答案 使用插值而不是连接更容易和更具可读性:dear=""string="hello#{'mydear'unlessdear.empty?},goodmo

  8. ruby - 如何在数组中间插入一个数组? - 2

    我有一个Ruby数组[1,4]。我想在中间插入另一个数组[2,3],这样它就变成了[1,2,3,4]。我可以使用[1,4].insert(1,[2,3]).flatten实现这一点,但是有更好的方法吗? 最佳答案 您可以通过以下方式进行。[1,4].insert(1,*[2,3])insert()方法处理多个参数。因此,您可以使用splat运算符*将数组转换为参数。 关于ruby-如何在数组中间插入一个数组?,我们在StackOverflow上找到一个类似的问题:

  9. ruby - 用 ruby​​ 将 2 个破折号插入这个字符串的最短方法是什么? - 2

    这是字符串:04046955104021109我需要这样格式化:040469551-0402-1109用ruby​​做到这一点的最短/最有效的方法是什么? 最佳答案 两个简单的插入就可以了:example_string.insert(-9,'-').insert(-5,'-')负数表示您从字符串末尾开始计数。如果您愿意,也可以从头数起:example_string.insert(9,'-').insert(14,'-') 关于ruby-用ruby​​将2个破折号插入这个字符串的最短方法是

  10. ruby-on-rails - 如何将变量值插入 ERB 模板中的 HTML 标签? - 2

    我有一个偏爱:如何将像o.office这样的值插入到属性中?value="#{o.office}"无效。 最佳答案 'type='text'/>或者你可以使用表单助手 关于ruby-on-rails-如何将变量值插入ERB模板中的HTML标签?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/6172174/

随机推荐