gpt4 book ai didi

parsing - 如何使用解析器表达式语法处理先前声明的常量?

转载 作者:行者123 更新时间:2023-11-29 08:05:33 24 4
gpt4 key购买 nike

假设我在玩具 DSL 中有以下内容:

int foo(int bar = 0);

使用诸如 rust-peg 之类的工具,我可以定义一些简单的解析器表达式语法 (PEG) 规则来匹配它(假设适当的结构 FnProto 和 'Arg'):

function -> FnProto
= t:type " " n:name "(" v:arglist ");"
{ FnProto { return_type:t, name:n, args:v } }

arglist -> Vec<Arg>
= arg ** ","

arg -> Arg
= t:type " " n:name " = " z:integer { Arg { typename:t, name:n, value:z } }

type -> String
= "int" { match_str.to_string() }

name -> String
= [a-zA-Z_]+[a-zA-Z0-9_] { match_str.to_string() }

integer -> i64
= "-"? [0-9]+ { match_str.parse().unwrap() }

在实践中,这些简单的规则是不够的,但它们可以用来说明我的观点。

现在考虑以下情况,其中 bar 的默认值是先前在同一文件中定义的常量:

int BAZ = 0xDEADBEEF;

int foo(int bar = BAZ);

现在,解析函数的规则不仅需要接受整数文字作为默认参数值,还需要接受任何先前声明的常量。

我可以通过一次来解析常量并在第二次通过时替换适当的值,但我真的必须求助于两次吗?有什么方法可以在规则中引用以前解析的数据吗?

最佳答案

您混淆了“解析”(有效程序的识别,可能包括捕获它的表示 [例如,作为 AST])和语义分析和/或执行。

您的解析器应该定义语言中合法的句法。仅此而已,仅此而已。您也许能够编写一些语义无意义的程序,解析器不会提示。

解析完文本后,您现在需要对解析后的数据(而非源文本)进行“其他遍历”,以构建经典的编译器结构,例如符号表,并检查符号的所有使用是否有效。要进行其他传递,可以说您可以重新解析文本,但您已经根据假设完成了一次。这里的标准解决方案是让第一个解析构建一个表示程序基本细节的抽象语法树 (AST)。那些“其他遍”通过遍历 AST 而不是再次解析源文本来操作。

这些都是标准编译器类(class)和书籍中讲授的经典内容。如果您真的想构建一种编程语言,那么您将需要这种背景。

关于parsing - 如何使用解析器表达式语法处理先前声明的常量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29057443/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com