如何在bison和flex中使用缩进作为块分隔符 [英] How to use indentation as block delimiters with bison and flex

查看:0
本文介绍了如何在bison和flex中使用缩进作为块分隔符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何在bison+flex中将缩进实现为块分隔符。就像巨蟒一样。我正在编写自己的编程语言(主要是为了好玩,但我打算将其与游戏引擎一起使用),我会尝试想出一些特殊的东西,使样板程序最小化,开发速度最大化。

我已经用C编写了一个编译器(实际上是`langToy‘到Nasm的转换器),但失败了。由于某种原因,它只能处理整个源文件中的一个字符串(嗯,我已经醒了超过48小时-所以……你知道,大脑崩溃)。

我不知道是花括号和/或Begin->End更容易实现(我在这方面没有问题),还是只是我的大脑锁定了。

提前谢谢!


更新:好的,我不知道如何使用flex。我在向解析器返回多个DEDENT时遇到问题。Flex/Bison对我来说相对较新。


更新2: 这是我到目前为止想出的flex文件;它还没有完全理解:

%x t
%option noyywrap

%{
  int lineno = 0, ntab = 0, ltab = 0, dedent = 0;
%}

%%

<*>
  { ntab = 0; BEGIN(t); }
<t>	  { ++ntab; }
<t>.   { int i; /* my compiler complains not c99 if i use for( int i=0... */
         if( ntab > ltab )
           printf("> indent >
");
         else if( ntab < ltab )
           for( i = 0; i < ltab - ntab; i++ )
             printf("< dedent <
");
         else
           printf("=        =
");

         ltab = ntab; ntab = 0;
         BEGIN(INITIAL);
         /* move to next rule */
         REJECT;}
.    /* ignore everything else for now */

%%

main()
{
  yyin = fopen( "test", "r" );
  yylex();
}

你可以试着玩弄它,也许你会看到我错过了什么。在Haxe中,返回多个降级将是一种轻松的方式(返回t_dedent(Num);)。

此代码并不总是与缩进/缩进正确匹配。


更新3:我想我会放弃对flex的希望,用我自己的方式来做,如果有人知道如何在flex中做到这一点,我无论如何都会很高兴听到它。

推荐答案

您需要做的是让Flex计算每一行开头的空格数量,并插入适当数量的缩进/UNINDENT标记,以便解析器用来对事物进行分组。一个问题是您希望如何处理制表符和空格--您是否只想让它们等同于固定的制表位,还是希望要求缩进保持一致(因此,如果一行以制表符开头,而下一行以空格开头,您将发出错误信号,这可能会更难一些)。

假设您想要固定的8列制表符,您可以使用类似

%{
/* globals to track current indentation */
int current_line_indent = 0;   /* indentation of the current line */
int indent_level = 0;          /* indentation level passed to the parser */
%}

%x indent /* start state for parsing the indentation */
%s normal /* normal start state for everything else */

%%
<indent>" "      { current_line_indent++; }
<indent>"	"     { current_line_indent = (current_line_indent + 8) & ~7; }
<indent>"
"     { current_line_indent = 0; /*ignoring blank line */ }
<indent>.        {
                   unput(*yytext);
                   if (current_line_indent > indent_level) {
                       indent_level++;
                       return INDENT;
                   } else if (current_line_indent < indent_level) {
                       indent_level--;
                       return UNINDENT;
                   } else {
                       BEGIN normal;
                   }
                 }

<normal>"
"     { current_line_indent = 0; BEGIN indent; }
... other flex rules ...

您必须确保以缩进模式启动分析(以获得第一行的缩进)。

这篇关于如何在bison和flex中使用缩进作为块分隔符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆