在(V)C ++(2010)中创建一个类似于PEG的简单解析器

时间:2012-10-29 02:03:59

标签: c++ parsing visual-c++

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

逐行解析

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

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

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

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

2 个答案:

答案 0 :(得分:1)

Multipass让事情变得更轻松。在第一遍中,将事物分成标记,例如“=”,或“abababa”,或引号分隔的字符串,或空格块。不要破坏性(保留原始数据),但要将其分解为简单的块,并且可能有一个描述令牌是什么的小结构或枚举(即空格,字符串文字,标识符类型的东西等)

所以你的示例代码变成了: identifier(procedure)whitespace()标识符(Hello)whitespace()操作({)空格(\ n \ t)标识符(a)whitespace()操作(=)whitespace()数字(1)操作(;)空格(\ n) n \ t)等。

在这些令牌中,您可能还想在行上存储行号和偏移量(这有助于以后生成错误消息)。

快速测试是将其重新转换为原始文本。另一个快速测试可能是在html或其他东西中转出漂亮的打印版本(你将空白颜色设置为粉红色背景,标识符为浅蓝色,操作为浅绿色,数字为浅橙色),并查看您的标记生成器是否正在制作感。

现在,您的语言可能对空格不敏感。如果是这样的话就丢弃空白! (C ++不是,因为在//评论结束时需要换行了)

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

所以现在你有了这样的代币流。此时有很多方法。你可以抽出一些严肃的解析剁并构建一个CFG来解析它们。 (你知道CFG是什么吗?LR(1)?LL(1)?)

更简单的方法可能是更专注。查找运算符({)并通过向上和向下计数找到匹配的运算符(})。查找语言关键字(如过程),然后需要一个名称(下一个标记),然后是一个块(a {)。一个非常简单的语言的临时解析器可以正常工作。

我已经完成了一个非常简单的语言,其中解析器由一个非常简单的PDA组成。它可能适合你们。或者它可能不会。

答案 1 :(得分: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