查看正文内容

#!/usr/bin/perluse strict;   # parse.pl - inputs lex, outputs flattened ast
use warnings; # http://www.rosettacode.org/wiki/Compiler/syntax_analyzermy $h = qr/\G\s*\d+\s+\d+\s+/;  # header of each linesub error { die "*** Expected @_ at " . (/\G(.*\n)/ ?$1 =~ s/^\s*(\d+)\s+(\d+)\s+/line $1 character $2 got /r : "EOF\n") }sub want { /$h \Q$_[1]\E.*\n/gcx ? shift : error "'$_[1]'" }local $_ = join '', <>;
print want stmtlist(), 'End_of_input';sub stmtlist{/(?=$h (RightBrace|End_of_input))/gcx and return ";\n";my ($stmt, $stmtlist) = (stmt(), stmtlist());$stmtlist eq ";\n" ? $stmt : "Sequence\n$stmt$stmtlist";}sub stmt{/$h Semicolon\n/gcx ? ";\n" :/$h Identifier \s+ (\w+) \n/gcx ? want("Assign\nIdentifier\t$1\n",'Op_assign') . want expr(0), 'Semicolon' :/$h Keyword_while \n/gcx ? "While\n" . parenexp() . stmt() :/$h Keyword_if \n/gcx ?  "If\n" . parenexp() . "If\n" . stmt() .(/$h Keyword_else \n/gcx ? stmt() : ";\n") :/$h Keyword_print \n/gcx ? want('', 'LeftParen') .want want(printlist(), 'RightParen'), 'Semicolon' :/$h Keyword_putc \n/gcx ? want "Prtc\n" . parenexp() . ";\n", 'Semicolon' :/$h LeftBrace \n/gcx ? want stmtlist(), 'RightBrace' :error 'A STMT';}sub parenexp { want('', 'LeftParen') . want expr(0), 'RightParen' } # (expr)sub printlist{my $ast = /$h String \s+ (".*") \n/gcx ?"Prts\nString\t\t$1\n;\n" : "Prti\n" . expr(0) . ";\n";/$h Comma \n/gcx ? "Sequence\n$ast" . printlist() : $ast;}sub expr               # (sort of EBNF) expr = operand { operator expr }{my $ast =                                        # operand/$h Integer \s+ (\d+) \n/gcx ? "Integer\t\t$1\n" :/$h Identifier \s+ (\w+) \n/gcx ? "Identifier\t$1\n" :/$h LeftParen \n/gcx ? want expr(0), 'RightParen' :/$h Op_(negate|subtract) \n/gcx ? "Negate\n" . expr(8) . ";\n" :/$h Op_not \n/gcx ? "Not\n" . expr(8) . ";\n" :/$h Op_add \n/gcx ? expr(8) :error "A PRIMARY";$ast =                                           # { operator expr }$_[0] <= 7 && /$h Op_multiply \n/gcx ? "Multiply\n$ast" . expr(8) :$_[0] <= 7 && /$h Op_divide \n/gcx ? "Divide\n$ast" . expr(8) :$_[0] <= 7 && /$h Op_mod \n/gcx ? "Mod\n$ast" . expr(8) :$_[0] <= 6 && /$h Op_add \n/gcx ? "Add\n$ast" . expr(7) :$_[0] <= 6 && /$h Op_subtract \n/gcx ? "Subtract\n$ast" . expr(7) :$_[0] == 5 && /(?=$h Op_(less|greater)(equal)? \n)/gcx ? error 'NO ASSOC' :$_[0] <= 5 && /$h Op_lessequal \n/gcx ? "LessEqual\n$ast" . expr(5) :$_[0] <= 5 && /$h Op_less \n/gcx ? "Less\n$ast" . expr(5) :$_[0] <= 5 && /$h Op_greater \n/gcx ? "Greater\n$ast" . expr(5) :$_[0] <= 5 && /$h Op_greaterequal \n/gcx ?  "GreaterEqual\n$ast" . expr(5) :$_[0] == 3 && /(?=$h Op_(not)?equal \n)/gcx ? error 'NO ASSOC' :$_[0] <= 3 && /$h Op_equal \n/gcx ? "Equal\n$ast" . expr(3) :$_[0] <= 3 && /$h Op_notequal \n/gcx ? "NotEqual\n$ast" . expr(3) :$_[0] <= 1 && /$h Op_and \n/gcx ? "And\n$ast" . expr(2) :$_[0] <= 0 && /$h Op_or \n/gcx ? "Or\n$ast" . expr(1) :return $ast while 1;}

输出:

Sequence
Assign
Identifier      count
Integer         1
While
Less
Identifier      count
Integer         10
Sequence
Sequence
Prts
String          "count is: "
;
Sequence
Prti
Identifier      count
;
Prts
String          "\n"
;
Assign
Identifier      count
Add
Identifier      count
Integer         1

语法分析器(syntax analyzer)【Perl实现】相关推荐

  1. 编译器之语法分析器(syntax analyzer)

    语法分析器根据语法将标记流(来自词法分析器)转换为语法树. 任务描述 从"词法分析器" 中获取输出,并根据以下语法将其转换为抽象语法树(AST).输出应为扁平格式. 程序应从文件和 ...

  2. 《编译原理》实验报告——基于YACC的TINY语法分析器的构建

    一.实验要求 运用YACC,针对TINY语言,构造一个语法分析器.给出实验方案,实施并描述结果. 二.实验方案 (1)设计基于LEX的TINY词法分析器 (2)设计基于YACC的TINY语法分析器 ( ...

  3. java实现语法分析器_200 行 JS 代码,带你实现代码编译器

    一.前言 对于前端同学来说,编译器可能适合神奇的魔盒 ,表面普通,但常常给我们惊喜. 编译器,顾名思义,用来编译,编译什么呢?当然是编译代码咯 . 其实我们也经常接触到编译器的使用场景: React ...

  4. 递归下降语法分析器的构建_一文了解函数式查询优化器Spark SQL Catalyst

    大数据技术与架构点击右侧关注,大数据开发领域最强公众号! 暴走大数据点击右侧关注,暴走大数据!记录一下个人对sparkSql的catalyst这个函数式的可扩展的查询优化器的理解,目录如下: 0. O ...

  5. 编译器入门 语法分析器 java_从零开始写个编译器吧 - Parser 语法分析器

    Parser(语法分析器)的编写相对于 Tokenizer (词法分析器)要复杂得多,因此,在编写之前可能也会铺垫得更多一些.当然,本系列旨在"写出"一个编译器,所以理论方面只会简 ...

  6. 编译原理——实验叁——基于YACC的TINY语法分析器的构建

    一. 实验要求 运用YACC,针对TINY语言,构造一个语法分析器.给出实验方案,实施并描述结果. 二. 实验方案 (1)设计基于YACC的TINY词法分析器 (2)设计基于LEX的TINY语法分析器 ...

  7. 编译原理——实验叁预习报告——基于YACC的TINY语法分析器的构建

    一.实验目的: 运用YACC,针对给定的文法,构造一个语法分析器.给出实验方案,实施并描述结果. 二.实验预习提示 1.表达:针对5.5节中的calculator文法,设计输入和输出 2.观察:观察p ...

  8. Vczh Library++ 语法分析器开发指南

    Vczh Library++ 语法分析器开发指南 陈梓瀚 前言 在日常的开发工作中我们总是时不时需要写一些语法分析器.语法分析器不一定指的是一门语言的编译器前端,也有可能仅仅是一个自己设计格式的配置文 ...

  9. 自己动手开发编译器(十)miniSharp语法分析器

    经过前面四篇的铺垫,我们终于拥有了编写语法分析器的强大工具,现在可以正式开发一门编程语言的语法分析器了.我们先来定义miniSharp的语法规则,然后根据LL文法的特点进行一些调整,最后借助解析器组合 ...

  10. 编译原理c++基于LR分析表编写语法分析器

    具体要求 已知文法G[E]: E->E+T | T T->(E) | id | id[E] //其中E,T为非终结符,其余符号为终结符 (1)为该文法建立LR分析表.//通过构造项目集规范 ...

最新文章

  1. 互联网协议第六版部署提速 阿里专家详解全套安全解决方案
  2. P3121 [USACO15FEB]审查(黄金)Censoring (Gold)
  3. 二十一、深入Python强大的装饰器
  4. 22 Python IO、打印到屏幕、读取键盘输入、打开和关闭文件、文件定位、重命名和删除文件、Python里的目录、文件,目录相关的方法
  5. SAP BW系统日常维护日常工作及常见的Infopackage错误
  6. 解决SVN提交代码时的错误:“Could not execute PROPPATCH”
  7. 【opencv学习】Fast算法进行角点检测
  8. mysql如何创建用户代码_MySQl创建用户和授权的方法介绍(代码示例)
  9. Even better, if you don’t want to answer and
  10. 2017.9.6.语文
  11. 软件数字签名证书选购指南
  12. vue3.0脚手架搭建(vscode)
  13. 软件测试周刊(第12期):程序员在晋升之后会发生什么?
  14. 测试基础(三)No Risk, No Test,证实和证伪相结合
  15. java 获取mac字体_Mac OS X上的Java App无法正确打印字体
  16. 人世间最纯净的友情只存在于孩童时代
  17. 树莓派3B配置无线路由器
  18. vscode 下载慢解决方法
  19. Linux下shell显示用户名和主机名
  20. 蓝牙协议分析(2)_协议架构

热门文章

  1. 2018年内大892数据结构部分参考答案
  2. Windows驱动学习第一步,第一个Windows驱动
  3. Redis(狂神说 )学习使用笔记
  4. trickle 限制用户空间带宽
  5. Linux——设置汉字拼音输入法
  6. linux常用命令(六)命令执行顺序控制与管道
  7. L1, L2, smooth_L1 Loss函数python实现
  8. 计算机网络-因特网概述
  9. Delphi使用ADOconnection连接mysql数据库时的Connectionstring问题
  10. 还不了解什么是商业智能(BI)?看完这篇文章就懂了