如何使用缩进作为 bison 和 flex 的块分隔符

2023-11-21

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

我已经写了一个编译器(实际上是‘郎玩具’到 Nasm 翻译器)在 C 中,但失败了。由于某种原因,它只能处理整个源文件中的一个字符串(好吧,我已经醒了超过 48 小时 - 所以......你知道,大脑崩溃了)。

我不知道大括号和/或开始 -> 结束是否更容易实现(我这样做没有问题)或者是否只是我的大脑锁定了。

提前致谢!


Update:好吧,我不知道如何用 Flex 来做到这一点。我在向解析器返回多个 DEDENT 时遇到问题。 Flex/Bison 对我来说相对较新。


更新2:这是我到目前为止想出的 Flex 文件;它不太明白:

%x t
%option noyywrap

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

%%

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

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

%%

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

你可以尝试一下,也许你会看到我所缺少的。在 Haxe 中返回多个 dedent 会很容易( return t_dedent( num ); )。

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


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


您需要做的是让 flex 计算每行开头的空格数量,并插入适当数量的 INDENT/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>"\t"     { current_line_indent = (current_line_indent + 8) & ~7; }
<indent>"\n"     { 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>"\n"     { current_line_indent = 0; BEGIN indent; }
... other flex rules ...

您必须确保以缩进模式开始解析(以在第一行获得缩进)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用缩进作为 bison 和 flex 的块分隔符 的相关文章

随机推荐

  • Javascript 日期,这是我的错误还是我发现了错误?

    我的应用程序中有一个简单的 Javascript 部分 其中有一个链接 添加日期 它会在日期上添加 1 天 它总是工作得很好 除非日期是 11 07 2010 然后链接突然不再工作 它真的很奇怪 因为它只在特定日期 11 07 2010 挂
  • GCC 编译时抛出错误:错误:未知类型名称“FILE”

    我正在制作一个只写的函数 hello 到一个文件 我已将其放在另一个文件中 并将其标头包含在程序中 但 gcc 给出了一个错误 error unknown type name FILE 代码如下 app c include
  • 缩放 SKNode 不一致

    我已经创建了自己的解决方案 用于放大或缩小特定的 SKNode 而无需缩放整个场景 它似乎主要按照我期望的方式工作 有 2 个值得注意的例外 我希望在这里得到输入 首先是代码 该控制语句位于touchesMoved方法内 if touche
  • 使用jquery更改给定特定宽度范围的类名(媒体查询)

    我正在尝试修改以下 html div class col1 width8 img src images entity jpg div 我想使用媒体查询 但我不想修改css 而是将类名从width8替换为width6 对于下面的标准媒体查询来
  • iPhone 3GS 上后台线程消耗 100% CPU 导致潜在主线程

    在我的应用程序中 我在 NSOperationQueue 中执行 10 个异步 NSURLConnections 作为 NSInitationOperations 为了防止每个操作在连接有机会完成之前返回 我调用 CFRunLoopRun
  • 编辑表单中的 Django-Taggit

    这是一个模型类 class ModelName models Model pasta TaggableManager verbose name u Pasta 和一个表单模板 正常 P form as p 我想让一切都非常干净和有用 但结果
  • 使用“::”代替“module ...”作为 Ruby 命名空间

    在 Ruby 中 写法有区别吗class Foo Bar and module Foo class Bar用于命名空间 如果是这样 那又怎样 如果你使用class Foo Bar 但是Foo模块尚未定义 将会引发异常 而module Foo
  • Solr 通配符搜索

    如果我有一条包含关键字 Chris Muench 的记录 我希望能够匹配 Mue 或 Chr 我怎样才能用 solr 查询来做到这一点 目前我执行以下操作 results solr gt search Apache Solr Service
  • 使用 matplotlib 的内存泄漏

    这并不是一个错误报告 即使这些泄漏可能是由于 mpl 错误造成的 请解释所提出的问题 以寻求解决方法 问题很简单 绘制大量数据 使用plot 或scatter 清除 释放所有内容 垃圾收集 但仍然没有释放几乎所有内存 Line Mem us
  • 如何使用 Moment.js 排除两个日期之间的周末

    我试图在我的 JavaScript 代码中排除周末 我使用 moment js 并且很难为 天 选择正确的变量 到目前为止 我认为我需要通过将工作日变量更改为仅从第 1 天计数到第 5 天来排除第 6 天 星期六 和第 0 天 星期日 但不
  • 无需重新加载页面即可收到通知(例如 facebook 或 google plus 通知)

    将 Facebook 等通知发送到仪表板的理想机制是什么 我认为最好的方法是每 5 秒对 php 页面进行一次 Ajax 调用并检索通知 有没有更好的方法来进行类似的更改 它也应该适用于所有移动浏览器 我按照以下方式做 use post在j
  • 为什么 Graphics.MeasureString() 返回的数字高于预期数字?

    我正在生成收据 并使用 Graphics 对象调用 DrawString 方法来打印所需的文本 graphics DrawString string font brush widthOfPage 2F yPoint stringformat
  • Helm 3:连接到本地 Kubernetes 时出现 x509 错误

    我是一个完美的noob与 K8 一起 我安装了microk8s and Helm using snap在本地进行实验 我想知道我当前的问题是否来自于使用snap 据我了解 其目的是封装 环境 Ubuntu 20 04LTS helm ver
  • 将 ISO 8601 时间格式转换为正常持续时间

    我有一个持续时间字符串 PT1M33S 我想得到以下格式的结果 gt 01 33 谁能告诉我如何使用js或jquery做到这一点 这似乎不是时间格式 只是视频的持续时间 33 Seconds PT1M33S 1 Minute H 小时M 分
  • 如何从字符串中删除换行符?

    我有一个以下格式的字符串 string s This is a Test String n This is a next line t This is a tab n 我想删除所有出现的 n and r从上面的字符串 我努力了string
  • stl::multimap - 如何获取数据组?

    Multimap 本质上具有按键排序的数据组 我想要一种方法来访问这些单独的组并获取它们的聚合值 例如 在一个std multimap lt string int gt 我存储 Group1 1 Group1 2 Group1 3 Grou
  • 类型引用>() { }

    从几天前开始 我开始从事一个网络服务项目 该项目正在使用Jackson编组和解组JSON 对象 所以我的问题是 为什么我总是必须把 当我创建一个实例时TypeReference 我知道构造函数是protected 但为什么是protecte
  • 如果使用 bash 以外的任何东西,我怎样才能拥有 term.el (ansi-term) 跟踪目录

    使用 eshell 或 ansi term 和 bash 时 emacs 会根据您所在的目录更改默认目录变量 所以如果我搬到 home user code project然后使用 ido find file 打开一个文件 它以 CWD 启动
  • 当参数是重载函数时,重载解析如何工作?

    Preamble C 中的重载解析可能是一个过于复杂的过程 理解控制重载解析的所有 C 规则需要付出相当多的脑力劳动 最近我想到参数列表中重载函数名称的存在会增加重载解析的复杂性 由于它恰好是一个广泛使用的案例 所以我发布了一个问题并收到了
  • 如何使用缩进作为 bison 和 flex 的块分隔符

    我很想知道如何在 bison flex 中实现缩进作为块分隔符 就像在 python 中一样 我正在编写自己的编程语言 主要是为了好玩 但我打算将其与游戏引擎一起使用 我将尝试想出一些特殊的东西来最小化样板文件并最大化开发速度 我已经写了一