【问题标题】:How to use lexer rules for two separate lexer modes?如何为两种不同的词法分析器模式使用词法分析器规则?
【发布时间】:2014-06-12 09:12:34
【问题描述】:

我正在为一种语言构建一个解析器,该语言包含特殊预处理器部分中的预处理器指令(由{} 封闭)。其中之一类似于C#define

我想对预处理器部分使用孤岛语法在一次运行中对文件进行 lex。 当我点击#define 指令时,我想包含另一个岛语法,其中包含“常规”部分的所有标记(大约 200 个),除了预处理区域开始标记并在不同的通道上发出标记和当然有一个停止标记,它返回到预处理器岛语法。由于我解析的文件是有效的,因此真正删除预处理器区域起始令牌 { 并不是很重要,但会很好。

有没有办法“重用”两种模式的词法分析器规则(我可以向一个命名的非常量通道发出我可以在进入/离开岛时更改的值)?

这是一些示例源文件:

int a = 42;

{ // start preprocessor section

// simple single line #define
#define ABC 42

// will be fix "2 * 42" even if ABS is changed later on
#define DEF 2 * ABC

// multiple line define (all but last line needs to have a "\" before the newline
#define GHI   3 \
              + 4

// the definition can contain (almost) arbitrary code, except line comments, preprocessor sections and preprocessor statements
#define JKL  if (a > 23) then b = c + d; str = "} <- this must not be the end of the preprocessor section"; end_if;              

} // end preprocessor section

【问题讨论】:

    标签: c# antlr4


    【解决方案1】:

    您目前无法将在一种模式中定义的词法分析器规则重用/导入到另一种模式中。我通常会执行以下操作。

    LBRACE : '{';
    
    mode OtherMode;
    
      OtherMode_LBRACE : LBRACE -> type(LBRACE);
    

    由于 ANTLR 4 工具中的代码生成优化,由于在该规则中使用了 type 词法分析器命令,上述构造实际上不会创建单独的 OtherMode_LBRACE 标记。

    【讨论】:

    • 这就是我为“少数”规则做的事情。对于 200 条规则,您的方法是什么?
    • @Onur 在此表单中创建 200 个原始规则的副本。
    • 尽管我不手动执行样板代码(请参阅我的回答),但我还是带你走近了。
    【解决方案2】:

    我最终采用了简单地复制 Sam 提出的规则的方法。我首先尝试从另一种模式返回主模式,并在某个位置检查我是否将返回嵌入式操作,并使用设置“当前活动通道”并将这些添加到所有规则的操作,但这会使所有规则混乱并且没有“觉得做正确的事”。

    为了减少手动工作,我重新组织了我的词法分析器文件,现在可以很容易地复制要包含在其他模式中的规则,并使用这个正则表达式来转换它们并将它们插入到其他模式部分:

    搜索:

    ^\s*(([a-z_0-9]+)[ \t\n]*)(:.*?;)\n
    

    替换为(PPP_ 只是我选择的前缀):

     PPP_$1 : $2 -> type\($2\), channel\(2\); \n\t\t\t/*$3*/\n
    

    并使用正则表达式选项“忽略大小写”、“单行”、“多行”

    如果您不想将令牌发送到另一个通道,请删除 channel(2) 部分。 我选择的编辑(notepad++)要求我转义大括号,你的可能不需要。

    【讨论】:

      猜你喜欢
      • 2021-11-18
      • 1970-01-01
      • 2013-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多