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 ...
随机推荐
- C#.NET 大型通用信息化系统集成快速开发平台 4.0 版本 - 拆分表、联系方式的拆分?
当用户数据有接近10万时,而且多表的关联也比较频繁时,能把大表拆为小表,也会提高系统的性能,I/O.运算性能.当然以后用户数据会更大可能会到30-40万以上,所有有能力时适当拆表,分分合合,合合分分也 ...
- NET WebApi OWIN 实现 OAuth 2.0
NET WebApi OWIN 实现 OAuth 2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和 ...
- md5的C++实现
一.原理 前一阵子,想知道md5的原理查了一下资料,说得基本都一样,最后让我看懂的是这两个链接: http://blog.csdn.net/qf_study/article/details/26309 ...
- Theano2.1.2-基础知识之第一步:代数
来自:http://deeplearning.net/software/theano/tutorial/adding.html Baby Steps - Algebra 一.两个标量相加 在学习the ...
- 虚拟机开机提示Operating System not found解决办法
为了更好体验windows更多操作系统,有些用户会在VMware虚拟机中安装XP.win7或win8等等系统,有用户反映在虚拟机中安装XP开机后提示"Operating System not ...
- Google搜索的几个使用技巧——让你的搜索结果更准确
对于软件开发人员来说,不知道的内容在网上搜索是再正常不过的了.今天同事在组内分享了几个谷歌搜索的使用技巧,在此自己总结一下,希望可以帮到更多人. 在此之前先要唠叨几句,什么时候用百度,什么时候用谷歌? ...
- OS存储器管理(三) 虚拟存储器
基本概念与实现 1)局部性原理 在一段时间内,运行的作业程序仅访问(涉及到)一部分作业代码,即不会涉及整个地址空间.即在一段时间间隔内,仅装入一部分代码,作业照样能正常运行 2)虚拟存储器的引入 作业 ...
- Button、ImageButton及ImageView详解
Button.ImageButton及ImageView详解 在应用程序开发过程中,很多时候需要将View的background或者src属性设置为图片,即美观又支持点击等操作.常见的有Button. ...
- java 中遍历hashmap 和hashset 的方法
一.java中遍历hashmap: for (Map.Entry<String, Integer> entry : tempMap.entrySet()) { String ...
- Python 一些总结和比较
数据类型