0

对于一个学校项目,我需要解析一个包含简化的“假”编程语言的文本/源文件来构建一个AST。我看过boost::spirit,但是因为这是一个小组项目,而且大多数人似乎不愿意学习额外的库,而且讲师/助教建议倾向于在 C++ 上创建一个简单的库。我想过走那条路。有没有一些例子或关于如何开始的想法?我有一些尝试,但还没有真正成功......

逐行解析

  • 用一堆正则表达式测试每一行(1个用于过程/函数声明),一个用于赋值,一个用于while等......
    • 但我需要假设一行中没有多个语句:例如。a=b;x=1;
  • 当我到达容器语句、程序、while 等时,我将增加indent. 所以所有嵌套语句都将在此之下
  • 当我达到 a}我会减少缩进

有更好的想法或建议吗?我需要解析的示例代码(这里非常简化......)

procedure Hello {
    a = 1;
    while a {
        b = a + 1 + z; 
    }
}

另一个想法是将整个文件读入一个字符串,然后自上而下。匹配所有过程,然后捕获其中的所有内容,{ ... }然后开始匹配语句(以 结尾;)或容器while { ... }。这类似于 PEG 做事的方式?但我需要阅读整个文件

4

2 回答 2

1

多通道使事情变得更容易。在第一次通过时,将事物拆分为标记,例如“=”或“abababa”,或引号分隔的字符串或空格块。不要破坏性(保留原始数据),而是将事情分解成简单的块,并且可能有一个小的结构或枚举来描述令牌是什么(即空格、字符串文字、标识符类型的东西等) .

所以你的示例代码变成: identifier(procedure) whitespace( ) identifier(Hello) whitespace( ) operation({) whitespace(\n\t) identifier(a) whitespace( ) operation(=) whitespace( ) number(1 ) 操作(;) 空格(\n\t) 等。

在这些标记中,您可能还希望在行上存储行号和偏移量(这将有助于稍后生成错误消息)。

一个快速的测试是将其转回原始文本。另一个快速测试可能是在 html 或其他内容中转储漂亮的打印版本(您将空白着色为粉红色背景,标识符为浅蓝色,操作为浅绿色,数字为浅橙色),并查看您的标记器是否正在制作感觉。

现在,您的语言可能对空格不敏感。因此,如果是这种情况,请丢弃空格!(C++ 不是,因为//注释结束时需要换行来学习)

(注意:专业的语言解析器将尽可能接近一次通过,因为它更快。但你是学生,你的目标应该是让它工作。)

所以现在你有一个这样的令牌流。在这一点上有很多方法。您可以提取一些严重的解析部分并构建一个 CFG 来解析它们。(你知道什么是 CFG 吗?LR(1)?LL(1)?)

一种更简单的方法可能是更临时地做它。查找 operator({) 并通过上下计数找到匹配的 operator(})。查找语言关键字(如过程),然后需要一个名称(下一个标记),然后是一个块(a {)。一个非常简单的语言的临时解析器可能工作得很好。

我已经为一种非常简单的语言做到了这一点,其中解析器由一个非常简单的 PDA 组成。它可能对你们有用。或者它可能不会。

于 2012-10-29T02:21:38.467 回答
1

既然你提到了 PEG,我想加入我的开源项目:https ://github.com/leblancmeneses/NPEG/tree/master/Languages/npeg_c++

这是一个可以导出C++版本的可视化工具:http ://www.robusthaven.com/blog/parsing-expression-grammar/npeg-language-workbench

规则语法文档:http ://www.robusthaven.com/blog/parsing-expression-grammar/npeg-dsl-documentation

如果我正在编写自己的语言,我可能会查看 System.Linq.Expressions 中的终端/非终端,因为这些对于您的语法规则来说是一个很好的开始。

http://msdn.microsoft.com/en-us/library/system.linq.expressions.aspx

System.Linq.Expressions.Expression
System.Linq.Expressions.BinaryExpression
System.Linq.Expressions.BlockExpression
System.Linq.Expressions.ConditionalExpression
System.Linq.Expressions.ConstantExpression
System.Linq.Expressions.DebugInfoExpression
System.Linq.Expressions.DefaultExpression
System.Linq.Expressions.DynamicExpression
System.Linq.Expressions.GotoExpression
System.Linq.Expressions.IndexExpression
System.Linq.Expressions.InvocationExpression
System.Linq.Expressions.LabelExpression
System.Linq.Expressions.LambdaExpression
System.Linq.Expressions.ListInitExpression
System.Linq.Expressions.LoopExpression
System.Linq.Expressions.MemberExpression
System.Linq.Expressions.MemberInitExpression
System.Linq.Expressions.MethodCallExpression
System.Linq.Expressions.NewArrayExpression
System.Linq.Expressions.NewExpression
System.Linq.Expressions.ParameterExpression
System.Linq.Expressions.RuntimeVariablesExpression
System.Linq.Expressions.SwitchExpression
System.Linq.Expressions.TryExpression
System.Linq.Expressions.TypeBinaryExpression
System.Linq.Expressions.UnaryExpression
于 2012-10-29T18:34:51.413 回答