Writing a simple Lexer in PHP/C++/Java
catalog
. Comparison of parser generators
. Writing a simple lexer in PHP
. phc
. JLexPHP: A PHP Lexer(xx.lex.php) Created By Java By x.lex File Input
. JFlex
. JLex: A Lexical Analyzer Generator for Java
. PhpParser
0. Comparison of parser generators
Relevant Link:
https://en.wikipedia.org/wiki/Comparison_of_parser_generators
http://www2.cs.tum.edu/projekte/cup/examples.php
http://pygments.org/docs/lexers/
http://www.phpdeveloper.org/news/5678
1. Writing a simple lexer in PHP
0x1: Introduction
Router::connect('/login', array('Sessions::add'));
The map /login -> Sessions::add may be translated into the following token stream by the lexer
<T_MAP, "map">
<T_URL, "/login">
<T_BLOCKSTART, "->">
<T_IDENTIFIER, "Sessions::add">
he parser can parse the following notation
<whitespace> := [\s]
<map> := "map"
<url> := [a-z/]
<blockstart> := "->"
<identifier> := [a-zA-Z0-:]
<mapBlock> := <map> <whitespace>* <url>+ <whitespace>* <blockstart> <whitespace>* <identifier>+
very rule identified by a := is called a production rule. I leave the parsing part for a later post, because that would be too much for a single posting
0x2: Implementation
The basic idea is that we match a list of regexes against the current line. If one of them matches, we store that token and advance our offset to the first character after the match. If no token is found and we are not yet at the end of the line, raise an exception (because something invalid is in front of our offset).
Let's stick with the example already mentioned above. We want to create tokens for an input file like map /login -> Sessions::add or root -> Pages::home.
The first thing we need is an array of terminal symbols that map to token identifiers.
<?php
class Lexer {
protected static $_terminals = array(
"/^(root)/" => "T_ROOT",
"/^(map)/" => "T_MAP",
"/^(\s+)/" => "T_WHITESPACE",
"/^(\/[A-Za-z0-9\/:]+[^\s])/" => "T_URL",
"/^(->)/" => "T_BLOCKSTART",
"/^(::)/" => "T_DOUBLESEPARATOR",
"/^(\w+)/" => "T_IDENTIFIER",
);
}
?>
Now, let's implement a run method that accepts an array of source lines and returns an array of tokens. It calls the helper _match method that performs the actual matching and raises an exception if no token was found.
public static function run($source) {
$tokens = array(); foreach($source as $number => $line) {
$offset = ;
while($offset < strlen($line)) {
$result = static::_match($line, $number, $offset);
if($result === false) {
throw new Exception("Unable to parse line " . ($line+) . ".");
}
$tokens[] = $result;
$offset += strlen($result['match']);
}
} return $tokens;
}
ote that how we advance the offset further every iteration and work towards the end of the string. To get the full picture, here's the _match
helper method.
protected static function _match($line, $number, $offset) {
$string = substr($line, $offset); foreach(static::$_terminals as $pattern => $name) {
if(preg_match($pattern, $string, $matches)) {
return array(
'match' => $matches[],
'token' => $name,
'line' => $number+
);
}
} return false;
}
We use the preg_match method to check if one of our pattern matches the current string. If you look closely, you can see that all of our regexes start at the beginning of the line (^) and are enclosed (()) so we can find them exactly at the beginning and get the inner content. We also store the current line, because we need it in our parser and to display helpful error messages.
Let's run our lexer with some example input:
$input = array('root -> Foo::bar');
$result = Lexer::run($input);
var_dump($result);
0x3: Wrapping Up
One thing you need to be aware of is that you need to place your token regex in the correct order - namely from special to general. If we put the T_IDENTIFIER before T_ROOT, the root keyword would always be matched as an identifier. While I haven't tried it out yet
在一个完备的词法解析器中,匹配状态机应该是采取"贪婪策略",即尽可能地匹配最长的"词法模式"
Relevant Link:
http://nitschinger.at/Writing-a-simple-lexer-in-PHP
http://www.codediesel.com/php/building-a-simple-parser-and-lexer-in-php/
2. phc
phc is an open source compiler for PHP with support for plugins. In addition, it can be used to pretty-print or obfuscate PHP code, as a framework for developing applications that process PHP scripts, or to convert PHP into XML and back, enabling processing of PHP scripts using XML tools.
. phc for PHP programmers
) Compile PHP source into an (optimized) executable (supports entire PHP standard library).
) Compile a web application into an (optimized) extension (supports entire PHP standard library).
) Pretty-print PHP code.
) Obfuscate PHP code (--obfuscate flag - experimental).
) Combine many php scripts into a single file (--include flag - experimental).
) Optimize PHP code using classical compiler optimizations (in the dataflow branch - very experimental). . phc for tools developers
) Analyse, modify or refactor PHP scripts using C++ plugins.
) Convert PHP into a well-defined XML format, process it with your own tools, and convert it back to PHP.
) Operate on ASTs, simplified ASTs, or -address code.
) Analyse or optimize PHP code using an SSA-based IR (in the dataflow branch - very experimental).
0x1: Installation Instructions
. g++ version 3.4. or higher
. make
. Boost version 1.34 or higher
. PHP5 embed SAPI (version 5.2.x recommended; refer to PHP embed SAPI installation instructions for more details). This is required to compile PHP code with phc.
. Xerces-C++ if you want support for XML parsing (you don’t need Xerces for XML unparsing).
. Boehm garbage collector is used in phc, but not in code compiled by phc. If unavailable, it can be disabled with --disable-gc, but phc will leak all memory it uses.
//The following dependencies are optional:
. a DOT viewer such as graphviz if you want to be able to view the graphical output generated by phc (for example, syntax trees)
/*
Under Debian/Ubuntu, the following command will install nearly all dependencies:
apt-get install build-essential libboost-all-dev libxerces27-dev graphviz libgc-dev
*/
0x2: Running phc
<?php
echo "Hello world!";
?> phc -c helloworld.php -o helloworld
//This creates an executable helloworld, which can then be run
./helloworld
0x3: Traversing the Tree
<?php
$x = ;
if($x == )
echo "yes";
else
echo "no";
?>
phc解析得到的AST(抽象语法树)如下
Relevant Link:
http://www.phpcompiler.org/downloads.html
http://www.phpcompiler.org/
http://www.phpcompiler.org/doc/latest/install.html
http://www.phpcompiler.org/doc/latest/runningphc.html
http://www.phpcompiler.org/doc/latest/treetutorial1.html#treetutorial1
http://www.phpcompiler.org/doc/latest/manual.html
3. JLexPHP: A PHP Lexer(xx.lex.php) Created By Java By x.lex File Input
A lexer generator for PHP. It is based on JLex and requires Java to generate the lexer. Once generated, the lexer only requires PHP to run
0x1: x.lex(词法规则文件)
<?php # vim:ft=php
include 'jlex.php'; %% %{
//<YYINITIAL> L? \" (\\.|[^\\\"])* \" { $this->createToken(CParser::TK_STRING_LITERAL); }
/* blah */
%} %function nextToken
%line
%char
%state COMMENTS ALPHA=[A-Za-z_]
DIGIT=[-]
ALPHA_NUMERIC={ALPHA}|{DIGIT}
IDENT={ALPHA}({ALPHA_NUMERIC})*
NUMBER=({DIGIT})+
WHITE_SPACE=([\ \n\r\t\f])+ %% <YYINITIAL> {NUMBER} {
return $this->createToken();
}
<YYINITIAL> {WHITE_SPACE} { } <YYINITIAL> "+" {
return $this->createToken();
}
<YYINITIAL> "-" {
return $this->createToken();
}
<YYINITIAL> "*" {
return $this->createToken();
}
<YYINITIAL> "/" {
return $this->createToken();
}
<YYINITIAL> ";" {
return $this->createToken();
}
<YYINITIAL> "//" {
$this->yybegin(self::COMMENTS);
}
<COMMENTS> [^\n] {
}
<COMMENTS> [\n] {
$this->yybegin(self::YYINITIAL);
}
<YYINITIAL> . {
throw new Exception("bah!");
}
0x2: Lexer Generator(By Java Language)
//create the jar file
javac -Xlint:unchecked JLexPHP/Main.java
jar cvf JLexPHP.jar JLexPHP/*.class
//负责读取词法规则文件,并生成Lexer
java -cp JLexPHP.jar JLexPHP.Main simple.lex
aaarticlea/png;base64,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" alt="" />
编译得到simple.lex.php,这个.php文件中包含了PHP Lexer的代码逻辑
0x3: 调用simple.lex.php、解析PHP文件词法
<?php
$scanner = new Yylex(fopen("file", "r"));
while ($scanner->yylex())
; ?>
Relevant Link:
https://github.com/wez/JLexPHP/blob/master/JLexPHP/Main.java
https://github.com/wez/JLexPHP
http://wezfurlong.org/blog/2006/nov/parser-and-lexer-generators-for-php/
4. JFlex
. JFlex is a lexical analyzer generator (also known as scanner generator) for Java, written in Java.
. A lexical analyzer generator takes as input a specification with a set of regular expressions and corresponding actions. It generates a program (a lexer) that reads input, matches the input against the regular expressions in the spec file, and runs the corresponding action if a regular expression matched.
. Lexers usually are the first front-end step in compilers, matching keywords, comments, operators, etc, and generating an input token stream for parsers. Lexers can also be used for many other purposes.
. JFlex lexers are based on deterministic finite automata (DFAs). They are fast, without expensive backtracking.
. JFlex is designed to work together with the LALR parser generator CUP by Scott Hudson, and the Java modification of Berkeley Yacc BYacc/J by Bob Jamison. It can also be used together with other parser generators like ANTLR or as a standalone tool.
Relevant Link:
http://jflex.de/
5. JLex: A Lexical Analyzer Generator for Java
JLex is a lexical analyzer generator, written for Java, in Java
Relevant Link:
http://www.cs.princeton.edu/~appel/modern/java/JLex/
http://www.cs.princeton.edu/~appel/modern/java/JLex/current/manual.html
http://www.cs.princeton.edu/~appel/modern/java/JLex/current/manual.html#SECTION1
6. PhpParser
PhpParser generates a pure Java parser for PHP programs. Invoking this parser yields an explicit parse tree suitable for further analysis. This package is based upon
. JFlex 1.4.
. Cup .10k
. Grammar and lexer specifications of PHP 4.3..
0x1: Project settings for IntelliJ IDEA
. Project > Language Level: 1.7
. Modules > Sources: only src/java_cup, src/project, src/jFlex
0x2: Building and cleaning the project with Ant from within Eclipse
. Project > Properties > Builders
. Deactivate the Java Builder.
. New ...
. Select "Ant builder"
. Name it "Ant build" or "PhpParser build" (or any other suitable name).
. In the Main tab, select the build.xml in the project directory as Buildfile and the project directory as Base directory.
. In the Targets tab for "Manual build", select "build".
. In the Targets tab for "During a clean", select "clean all".
. OK the changes for both dialogs.
. Project > Build Project and Clean the project using Project > Clean ...
//Or you can build the project using the command line from within the project main directory
ant build
build.xml
<project name="PhpParser" basedir="." default="build">
<!-- PROPERTIES *************************************************************--> <!-- java/javac properties -->
<property name="src.dir" value="src"/>
<property name="src.project.dir" value="${src.dir}/project"/>
<property name="src.spec.dir" value="${src.dir}/spec"/>
<property name="src.jflex.dir" value="${src.dir}/JFlex"/>
<property name="src.cup.dir" value="${src.dir}/java_cup"/> <property name="build.dir" value="build"/>
<property name="build.java.dir" value="${build.dir}/java"/>
<property name="build.class.dir" value="${build.dir}/class"/> <property name="lexparse.package" value="at.ac.tuwien.infosys.www.phpparser"/>
<property name="lexparse.dir" value="${build.java.dir}/at/ac/tuwien/infosys/www/phpparser"/> <property name="javadoc.dir" value="doc/html"/>
<property name="javadoc.lexparse.dir" value="${javadoc.dir}/phpparser"/> <!-- lexer generator and generated lexer -->
<property name="lexgen.main" value="JFlex.Main"/>
<property name="lexgen.input" value="${src.spec.dir}/php.jflex"/>
<!-- the lexer name is specified with the %class option in the input file -->
<property name="lexer.name" value="PhpLexer"/>
<property name="lexer.source" value="${lexer.name}.java"/>
<property name="lexer.class" value="${lexer.name}.class"/> <!-- parser generator and generated parser -->
<property name="parsegen.main" value="java_cup.Main"/>
<property name="parsegen.input" value="${src.spec.dir}/php.cup"/>
<!-- CAUTION: when changing this property, consult the parser generator's input file first -->
<property name="parser.name" value="PhpParser"/>
<property name="parser.source" value="${parser.name}.java"/>
<property name="parser.sym.name" value="PhpSymbols"/>
<property name="parser.sym.source" value="${parser.sym.name}.java"/> <!-- classpath -->
<path id="classpath">
<pathelement location="${build.class.dir}"/>
<!-- -necessary because of JFlex Messages bundle -->
<pathelement location="${src.jflex.dir}"/>
</path> <!-- TARGETS ****************************************************************--> <target name="cup" description="Compiles the modified Cup.">
<mkdir dir="${build.class.dir}"/>
<javac srcdir="${src.cup.dir}" destdir="${build.class.dir}" debug="on" includeantruntime="false">
<compilerarg line="-encoding GBK"/>
<classpath refid="classpath"/>
</javac>
</target> <target name="jflex" description="Compiles the modified JFlex.">
<javac srcdir="${src.jflex.dir}" destdir="${build.class.dir}" debug="on" includeantruntime="false">
<compilerarg line="-encoding GBK"/>
<classpath refid="classpath"/>
</javac>
</target> <target name="lexer.source" depends="cup,jflex"
description="Uses the lexer generator to create a Java lexer from the input file.">
<mkdir dir="${lexparse.dir}"/>
<java classname="${lexgen.main}" fork="yes">
<arg value="${lexgen.input}"/>
<arg value="-d"/>
<arg value="${lexparse.dir}"/>
<classpath refid="classpath"/>
</java>
</target> <target name="parser.source" depends="cup"
description="Uses the parser generator to create a Java parser from the input file.">
<mkdir dir="${lexparse.dir}"/>
<java classname="${parsegen.main}" fork="yes">
<arg value="-parser"/>
<arg value="${parser.name}"/>
<arg value="-symbols"/>
<arg value="${parser.sym.name}"/>
<arg value="-nonterms"/>
<arg value="-expect"/>
<arg value=""/>
<arg value="${parsegen.input}"/>
<classpath refid="classpath"/>
</java>
<move file="${basedir}/${parser.source}" todir="${lexparse.dir}"/>
<move file="${basedir}/${parser.sym.source}" todir="${lexparse.dir}"/>
</target> <target name="javac"
description="Internal target for Java development. Doesn't try to generate lexer and parser.">
<mkdir dir="${build.class.dir}"/>
<javac destdir="${build.class.dir}" debug="on" includeantruntime="false">
<compilerarg line="-encoding GBK"/>
<src>
<pathelement path="${src.project.dir}"/>
<pathelement path="${build.java.dir}"/>
</src>
<classpath refid="classpath"/>
</javac>
</target> <target name="javadoc" depends="javac" description="Generates JavaDoc.">
<javadoc destdir="${javadoc.lexparse.dir}" packagenames="${lexparse.package}" Windowtitle="PhpParser 1.0">
<sourcepath>
<pathelement path="${src.project.dir}"/>
<pathelement path="${build.java.dir}"/>
</sourcepath>
<classpath refid="classpath"/>
</javadoc>
</target> <target name="build" depends="lexer.source,parser.source,javac,javadoc"
description="Builds the whole project together with the generated lexer and parser."/> <target name="clean" description="Cleans up.">
<delete dir="${build.java.dir}"/>
<delete dir="${build.class.dir}"/>
<delete dir="${graphs.dir}"/>
<delete file="${jar.file}"/>
</target> <target name="cleanall" depends="clean" description="Cleans up JFlex, Cup and JavaDoc as well.">
<delete dir="${lib.dir}/JFlex"/>
<delete dir="${lib.dir}/java_cup"/>
<delete dir="${javadoc.dir}"/>
</target> <target name="dist">
<mkdir dir="dist"/>
</target> <target name="help">
<echo message="You probably want to do 'ant build'. Otherwise, type 'ant -projecthelp' for help."/>
</target>
</project>
编译得到的Java版本的Lexer解析引擎,我们可以直接在代码中实例化并调用其中的函数
0x3: Usage
Example.java
import at.ac.tuwien.infosys.www.phpparser.*;
import java.io.*;
import java.util.*; class Example { public static void main(String[] args) { if (args.length == ) {
System.out.println("Please specify one or more PHP files to be parsed.");
System.exit();
} for (int i = ; i < args.length; i++) { String fileName = args[i]; ParseTree parseTree = null;
try {
PhpParser parser = new PhpParser(new PhpLexer(new FileReader(fileName)));
ParseNode rootNode = (ParseNode) parser.parse().value;
parseTree = new ParseTree(rootNode);
} catch (FileNotFoundException e) {
System.err.println("File not found: " + fileName);
System.exit();
} catch (Exception e) {
System.err.println("Error parsing " + fileName);
System.err.println(e.getMessage());
e.printStackTrace();
System.exit();
} System.out.println("*** Printing tokens for file " + fileName + "...");
for (Iterator iter = parseTree.leafIterator(); iter.hasNext(); ) {
ParseNode leaf = (ParseNode) iter.next();
System.out.println(leaf.getLexeme());
}
}
} }
编译
pushd D:\eclipse-javaEE\workspace\phpparser\doc\example
javac -classpath ../../build/class Example.java
运行
java -classpath ../../build/class:. Example test1.php test2.php
0x4: Directory layout
build.xml
README
build
class: generated java class files
java:generated java source files (PHP Lexer and Parser)
doc
various documentation files
src
java_cup: modified version of the Cup parser generator
jflex: modified version of the JFlex scanner generator
project: parse tree data structures
spec: specification (input) files for Cup and JFlex
Relevant Link:
https://github.com/oliverklee/phpparser/blob/master/src/spec/php.cup
https://github.com/oliverklee/phpparser/blob/master/src/spec/php.jflex
https://github.com/oliverklee/phpparser
Copyright (c) 2015 LittleHann All rights reserved
Writing a simple Lexer in PHP/C++/Java的更多相关文章
- Writing a Simple Publisher and Subscriber
用c++实现一个publisher/subscriber publisher #include "ros/ros.h" #include "std_msgs/String ...
- Writing a Simple YARN Application 从hadoop生态抽出yarn ,单独使用yarn
Apache Hadoop 2.9.1 – Hadoop: Writing YARN Applications https://hadoop.apache.org/docs/current/hadoo ...
- Writing a Simple Service and Client (C++)
此前说的publisher/subscriber都是广播式的,subscriber被动地接收消息,二者没有request/response这种交互. Service Node Client Node ...
- Apache POI – Reading and Writing Excel file in Java
来源于:https://www.mkyong.com/java/apache-poi-reading-and-writing-excel-file-in-java/ In this article, ...
- 111个知名Java项目集锦,包括url和描述
转:http://www.cnblogs.com/wangs/p/3282183.html 项目名称 项目描述 ASM Java bytecode manipulation framework A ...
- java Serialization and Deserializaton
This article from JavaTuturial Java provides a mechanism, called object serialization where an objec ...
- Thinking in Java from Chapter 15
From Thinking in Java 4th Edition. 泛型实现了:参数化类型的概念,使代码可以应用于多种类型.“泛型”这个术语的意思是:“适用于许多许多的类型”. 如果你了解其他语言( ...
- Java日期格式化
翻译人员: 铁锚 翻译时间: 2013年11月17日 原文链接: Simple example to show how to use Date Formatting in Java 代码示例如下, ...
- Java log code example
Java log example Logrecord filter import java.util.logging.Filter; import java.util.logging.Level; i ...
随机推荐
- C10K 问题引发的技术变革
C10K 问题引发的技术变革 http://rango.swoole.com/archives/381
- QT 数据库编程四
//vmysql.cpp #include "vmysql.h" #include <QMessageBox> Vmysql::Vmysql() { mysql_ini ...
- noi1696 逆波兰表达式
1696:逆波兰表达式 http://noi.openjudge.cn/ch0303/1696/ 总时间限制: 1000ms 内存限制: 65536kB 描述 逆波兰表达式是一种把运算符前置的算术 ...
- 目录结构-内置(AJAX)帮助文档
Discuz common.js 内置(AJAX)函数帮助文档 作者:cr180 / 整理日期:1970-01-01 / 个人站点:www.cr180.com / Discuz超级管家 showMen ...
- Java类加载和类反射回顾
今天学习Spring,突然想重新复习一下Java类加载和类反射的.巩固一下底层原理.部分参考了李刚老师的<疯狂Java讲义>和陈雄华.林开雄的<Spring3.x企业应用开发实战&g ...
- snr ber Eb/N0之间的区别与联系
信噪比(S/N)是指传输信号的平均功率与加性噪声的平均功率之比,载噪比(C/N)指已经调制的信号的平均功率与加性噪声的平均功率之比,它们都以对数的方式来计算,单位为dB. 对同一个传输系统而言,载噪比 ...
- getopt
头文件 #include<unistd.h> 定义函数 int getopt(int argc,char * const argv[ ],const char * optstring); ...
- iOS 自定义NavigationBar右侧按钮rightBarButtonItem--button
//两个按钮的父类view UIView *rightButtonView = [[UIView alloc] initWithFrame:CGRectMake(, , , )]; //历史浏览按钮 ...
- Java--剑指offer(2)
6.把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. a)使用ArrayList来存放元素 public class Solution { public static int min ...
- nginx安装配置+清缓存模块安装
经过一段时间的使用,发现nginx在并发与负载能力方面确实优于apache,现在已经将大部分站点从apache转到了nginx了.以下是nginx的一些简单的安装配置. 环境 操作系统:CentOS. ...