LaTeX中的TikZ绘图功能很强,为了方便以后用到的时候好查询,所以这里把自己绘制过的内容记录在CSDN博客中。

在以下环境测试过

  • 操作系统:Ubuntu 16.04 64位桌面版
  • LaTeX工具:TeXstudio 2.10.8
  • 编译方式:LuaLaTeX
示例一、编译器结构图

  原图选自裘巍老师所著的《编译器设计之路》。下面介绍我用LaTeX绘制的过程、代码与一些说明。

  过程介绍

  1. 包含tikz宏包,并且载入要使用的库。在本例中就是\usepackage{tikz}与\usetikzlibrary{positioning, arrows.meta}两条命令。在我使用的Ubuntu系统中,通过命令sudo apt install texlive-all安装,tikz的这些库就包含在其中(后面示例中用到的宏包与库也是如此)。我很久没有使用Windows,不清楚其下的情况。
  2. 先定义好需要的样式(style)。本例中先定义了要用到的方框与箭头的样式。当然,这是因为有现成的图形参照,如果没有也可后面再定义。先定义好需要的样式(style)。一般我会把style单独放在一个文件中由主文件来调用。
  3. 绘制方框。
  4. 绘制连线。

  完整代码

\documentclass{article}
%
\usepackage{ctex}
\usepackage{geometry}
\usepackage[dvipsnames, svgnames, x11names]{xcolor}
\usepackage{tikz}
%
\usetikzlibrary{positioning, arrows.meta}
%
\begin{document}
%
% 定义方框样式
\tikzset{rect1/.style = {shape = rectangle,draw = green,text width = 3cm,align = center,minimum height = 1cm,}
}
% 定义箭头样式
\tikzset{arrow1/.style = {draw = purple, thick, -{Latex[length = 4mm, width = 1.5mm]},}
}
% 双箭头
\tikzset{arrow2/.style = {draw = purple, thick, {Latex[length = 4mm, width = 1.5mm]}-{Latex[length = 4mm, width = 1.5mm]},}
}
\begin{center}\begin{tikzpicture}% 绘制中间方框\node[rect1, fill = green!60!white](词法){词法分析};\node[rect1, fill = green!40!white, below = of 词法](语法){语法分析};\node[rect1, fill = green!20!white, below = of 语法, text width = 5cm](语义中间){语义分析、中间表示生成};\node[rect1, fill = green!60!black, below = of 语义中间](优化){\color{white}代码优化};\node[rect1, fill = green!30!black, below = of 优化](生成){\color{white}代码生成};% 绘制两侧方框\node[rectangle, fill = red!20!white, draw = red, text width = 0.7cm, minimum height = 4cm, align = center, left = 2cm of 语义中间](符号){符号表管理};\node[rectangle, fill = blue!20!white, draw = blue, text width = 0.7cm, minimum height = 4cm, align = center, right = 2cm of 语义中间](出错处理){出错处理};% 绘制中间连线\draw[arrow1](0, 50pt)node[right, yshift = -15pt]{输入源程序} -- (词法);\draw[arrow1](词法) -- node[right]{单词流}(语法);\draw[arrow1](语法) -- node[right]{文法}(语义中间);\draw[arrow1](语义中间) -- node[right]{中间表示}(优化);\draw[arrow1](优化) -- node[right]{优化后中间表示}(生成);\draw[arrow1](生成) -- node[right, yshift = 5pt, xshift = 5pt]{目标代码}++(0, -50pt);% 绘制两侧连线\draw[arrow2](符号) -- (词法.west);\draw[arrow2](符号) -- (语法.west);\draw[arrow2](符号) -- (语义中间);\draw[arrow2](符号) -- (优化.west);\draw[arrow2](符号) -- (生成.west);\draw[arrow2](出错处理) -- (词法.east);\draw[arrow2](出错处理) -- (语法.east);\draw[arrow2](出错处理) -- (语义中间);\draw[arrow2](出错处理) -- (优化.east);\draw[arrow2](出错处理) -- (生成.east);% 绘制虚线框\draw[thick, dashed, draw = purple](-125pt, 27pt)node[below right]{编译器前端} -- (125pt, 27pt) -- (125pt, -250pt) -- (-125pt, -250pt)node[above right]{编译器后端} -- (-125pt, 27pt);\draw[thick, dashed, draw = purple](-125pt, -135pt) -- (125pt, -135pt);\end{tikzpicture}\\\heiti 图 1-2 编译器结构图\songti
\end{center}
%
\end{document}

效果如下:

说明
  1. 绘制方框的语句格式一般是:

\node[样式](名称){标题};

注意结尾的分号,绘制线条的语句最后先要加分号。名称是调用时使用,可以用汉字,标题是显示出来的文字,二者不一样。
  2. 样式的内容挺多的,方框中一般会用到形状(shape)、边框颜色(draw)、填充色(fill)、宽度(text width)、最小高度(minimum height)。颜色方面可以参考xcolor宏包的说明文档。长度单位有好几个,我一般常用的是pt与cm,1pt=0.351mm。
  3. 位置的表示也包含在样式定义中,一般形式是:方位 = 尺寸 of 参考对象。方位包括left、right、below、above、below left、below right、above left、above right 8种,要注意below left这样的顺序不能颠倒。
  4. 这里我们绘制箭头的库选用的是arrows.meta(24种箭头),这个库比arrows(14种)要丰富些。箭头的形状有很多种,详情请参考arrows.meta的24种箭头。本例中箭头样式选的是Latex样式,其后的length = 4mm, width = 1.5mm代表箭头的长宽,可以通过这两个参数调整箭头的锋锐程度。大家可以根据需要设置。
  5. 在线条上加文字的方法是通过加入node来实现,注意node在连线(即–)中的位置,如果放在–左边就表示文字是在线段的左边,反之在右边。实际上我们可以通过xshift、yshift两个参数来随意调整位置。
  6. 语句:

\draw[arrow1](0, 50pt)node[right, yshift = -15pt]{输入源程序} -- (词法);

其中的(0, 50pt)是指在绝对坐标0, 50pt处开始绘制,图形坐标的原点(0, 0)就是代码中第一个方框的中心处。如果我们在(0, 50pt)前加两个加号,例如++(0, 50pt),那就变成了相对坐标,是相对于上一个节点。例如语句:

\draw[arrow1](生成) -- node[right, yshift = 5pt, xshift = 5pt]{目标代码}++(0, -50pt);

++(0, -50pt)的意思就是相对于“生成”这个节点向下移动50pt的坐标。当我们不清楚绝对坐标时就用相对坐标来绘制,挺方便的。

示例二、Pascal语言单元声明与变量声明格式示意图

  完整代码

\documentclass{article}
%
\usepackage{ctex}
\usepackage{geometry}
\usepackage[dvipsnames, svgnames, x11names]{xcolor}
\usepackage{tikz}
%
\usetikzlibrary{positioning, arrows.meta, calc}
%
% 定义箭头样式
\tikzset{arrow1/.style = {draw = purple, thick, -{Latex[length = 4mm, width = 1.5mm]},}
}
% 非终端
\tikzset{nonterminal/.style = {rectangle,align = center,minimum size = 6mm,very thick,draw = red!50!black!50,top color = white,bottom color = red!50!black!20,}
}
% 终端
\tikzset{terminal/.style = {rectangle,align = center,minimum size = 6mm,rounded corners = 3mm,very thick,draw = black!50,top color = white,bottom color = black!20,}
}
%
\begin{document}
\begin{center}\begin{tikzpicture}[node distance = 0.5cm]\node[terminal, text width = 1.6cm](uses){USES};\node[nonterminal, text width = 1.6cm, right =  1cm of uses](unit){单元名};\node[terminal, right = 1cm of unit](semicolon){;};\node[terminal, below = of unit](comma){,};\draw[arrow1](uses)--(unit);\draw[arrow1](unit)--(semicolon);\draw[arrow1](semicolon)--++(30pt, 0);\draw[arrow1]($ (unit.east)+(3mm, 0) $)|-(comma);\draw[arrow1](comma)-|($ (unit.west)-(6mm, 0) $);\end{tikzpicture}
\end{center}
\begin{center}\begin{tikzpicture}\node[terminal, text width = 1.6cm](var){VAR};\node[nonterminal, text width = 1.6cm, right =  1cm of var](list){变量标识符列表};\node[terminal, right = 1cm of list](colon){:};\node[nonterminal, text width = 1.6cm, right =  1cm of colon](type){类型};\node[terminal, right = 1cm of type](semicolon1){;};\node[terminal, below = of list](semicolon2){;};\node[terminal, below = 2cm of colon](semicolon3){;};\draw[arrow1](var)--(list);\draw[arrow1](list)--(colon);\draw[arrow1](colon)--(type);\draw[arrow1](type)--(semicolon1);\draw[arrow1](semicolon1)--++(30pt, 0);\draw[arrow1]($ (list.east)+(3mm, 0) $)|-(semicolon2);\draw[arrow1](semicolon2)-|($ (list.west)-(6mm, 0) $);\draw[arrow1]($ (type.east)+(3mm, 0) $)|-(semicolon3);\draw[arrow1](semicolon3)-|($ (list.west)-(6mm, 0) $);\end{tikzpicture}
\end{center}
\end{document}

效果如下:

说明
  1. 本例中因为使用了一些计算,所以引入了TikZ中的calc库,大家在usetikzlibrary命令处可以看见。
  2. 圆角矩形的绘制就是加入rounded corners参数,当文字很少时,如上例中的分号与逗号,这个圆角矩形就变成了圆圈(实际上,这与minimum size的设置也有关)。
  3. 从线段中间开始画线的方法,大家在代码中可以看见,代码意思很明显,不再解释。
  4. 通过top color与bottom color的设置,实现了过渡效果。
  5. 在语句“…(3mm, 0) $)|-(comma);”中,两个节点间的“|-”表示线段是先画竖线,再画横线,画多长,系统会自动判断。
  6. 在“变量标识符列表”的定义语句中设置了text width参数,如果不设置的话,文字就不会换行。

示例三、Pascal语言单函数或过程声明格式示意图

  代码

\hspace{-3cm}{
\begin{minipage}{15.4cm}\begin{tikzpicture}[node distance = 0.7cm]\node[terminal](function){FUNCTION};\node[nonterminal, right = of function](name1){函数名};\node[terminal, right = of name1](left){(};\node[terminal, right = of left](var){VAR};\node[nonterminal, right = of var](para){形参名};\node[terminal, right = of para](colon1){:};\node[nonterminal, right = of colon1](type1){类型名};\node[terminal, right = of type1](right){)};\node[terminal, right = of right](colon2){:};\node[nonterminal, right = of colon2](type2){类型名};\node[terminal, right = of type2](semicolon1){;};\node[terminal, below = of para](semicolon2){;};
% ----------------------------------------------------------\draw[arrow1](function)--(name1);\draw[arrow1](name1)--(left);\draw[arrow1](left)--(var);\draw[arrow1](var)--(para);\draw[arrow1](para)--(colon1);\draw[arrow1](colon1)--(type1);\draw[arrow1](type1)--(right);\draw[arrow1](right)--(colon2);\draw[arrow1](colon2)--(type2);\draw[arrow1](type2)--(semicolon1);\draw[arrow1]($ (var.west)+(-3mm, 0) $)--++(0, 6mm)-|($ (var.east)+(3mm, 0) $);\draw[arrow1]($ (type1.east)+(3mm, 0) $)|-(semicolon2);\draw[arrow1](semicolon2)-|($ (var.west)-(3mm, 0) $);\draw[arrow1]($ (name1.east)+(3mm, 0) $)--++(0, -20mm)-|($ (right.east)+(3mm, 0) $);
% ----------------------------------------------------------\node[nonterminal, below = 2.7cm of function, xshift = 1cm](description){说明部分};\node[terminal, right = of description](begin){BEGIN};\node[nonterminal, right = of begin, text width = 1.6cm](statement){语句};\node[terminal, right = of statement](semicolon3){;};\node[terminal, right = of semicolon3, text width = 1.6cm](end){END};\node[terminal, right = of end](semicolon4){;};
% ----------------------------------------------------------\draw[arrow1](description)--(begin);\draw[arrow1](begin)--(statement);\draw[arrow1](statement)--(semicolon3);\draw[arrow1](semicolon3)--(end);\draw[arrow1](end)--(semicolon4);\draw[arrow1](semicolon4)--++(30pt, 0);\draw[arrow1](semicolon1)--++(0, -2.5cm)-|(description);\draw[arrow1]($ (semicolon3.east)+(3mm, 0) $)--++(0, -6mm)-|($ (begin.east)+(3mm, 0) $);\end{tikzpicture}
\end{minipage}

效果如下:

说明
  1. 此例的导言区部分与示例二的一样。
  2. 因为这幅图比较长,正常的A4纸显示不全,所以我用\hspace{-3cm}命令向左边距移了3厘米以保证完整显示。

LaTeX中TikZ绘图备忘一相关推荐

  1. LaTeX中TikZ绘图备忘二

    在以下环境测试过 操作系统:Ubuntu 16.04 64位桌面版 LaTeX工具:TeXstudio 2.10.8 编译方式:LuaLaTeX   示例四.chains库的使用   完整代码 \do ...

  2. Latex中TikZ绘制3D圆锥体

    1.Latex代码 \documentclass{article} \usepackage{tikz} \begin{document} \pagestyle{empty} \begin{tikzpi ...

  3. C#的委托事件在winform窗体中实现传值备忘

    用一个例子来说明吧,这样比较好明白一些. 就是打开主窗体,datagridview加载了一些数据,然后我们在打开的子窗体中,输入一些条件,让主窗体中的数据随着加载的条件来动态实现加载数据. 这就需要涉 ...

  4. Latex、Lyx学习备忘

    XeLaTex序: % 中文 \usepackage{fontspec,xltxtra,xunicode} \XeTeXlinebreaklocale "zh" \XeTeXlin ...

  5. Latex中TikZ初步使用

    ## 线段和点 \documentclass{article}\usepackage{tikz}\begin{document}\begin{tikzpicture} \draw[gray, thic ...

  6. 学习中常用T-CODE备忘

    /NEX 全退出 mm03 :查看物料 se11(查询表结构) se16(查询表数据) se37(查询function) se38(生成报表) bapi(查询接口) st05(数据跟踪) st12(性 ...

  7. Java如何获取JSON数据中的值 备忘

    Java如何获取JSON数据中的值 取出JsonArray中的object(orderNo) 嵌套 JsonObeject {    JsonObeject {       JsonArray [Ob ...

  8. LaTeX TikZ绘图——组合数学中棋盘多项式的画法

    写在前面 如题,最近组合数学作业需要画棋盘格,就是类似下面图1中的那样,但是网上找了各种中英文资料大多都不尽人意(画出来的都是真·国际象棋棋盘.....),经过不断的摸索与尝试,终于明白了Latex的 ...

  9. 怎样在电脑桌面设置便签备忘

    有不少的办公人士在工作时使用的是电脑,并且工作记录软件选择的是便签,在便签中记录办公备忘待办.日程安排.会议内容等,现在一些多功能的便签软件不止可以记录,还可以提醒办公.协助管理工作时间.多人团队办公 ...

最新文章

  1. 2022-2028年中国智能眼镜行业深度调研及投资前景预测报告
  2. BAT架构师分享之:大型网站技术架构
  3. 【JDBC 报错】Connections could not be acquired from the underlying database!
  4. 基于时序数据的微内核预警引擎架构设计
  5. sql优化ppt_Spark优化 | Spark 3.0 中七个必须知道的 SQL 性能优化
  6. IntelliJ IDEA license server
  7. epoll和select的区别
  8. 作者:赵国栋(1974-),男,中关村大数据产业联盟秘书长,北京大数据研究院副院长,北京汇冠新 技术股份有限公司独立董事...
  9. EasyDSS RTMP流媒体解决方案之直播录像自动清理方案
  10. 20-172-040-安装-Flink单机安装 flink-1.7.2-bin-hadoop27-scala_2.11
  11. 【Shell脚本学习指南笔记】重定向文件描述符 21
  12. Ubuntu14.04开启wifi热点(亲测有效)
  13. 使用移远EC200N-CN模组PING谷歌
  14. Java多线程高并发编程中点点理解
  15. 大型架构.net平台篇(WEB层均衡负载nginx)
  16. FlightGear Flight Simulator
  17. ReportMachine通过嵌套表达式计算某个值。
  18. 为了强调低电平有效,有时也将反相器图形符号中表示反相的小圆圈画在输入端,例如上图的左边一列反相器的画法
  19. KILE 报 contains an incorrect path. 错误
  20. HDU - 1242

热门文章

  1. 5G正式商用速率实测:中国移动表现最佳
  2. 常用笔记本电脑检测软件(含下载)
  3. php抓取curl下载文件,PHP 利用 Curl 函数实现多线程抓取网页和下载文件
  4. 最基础的远程控制来了,教你如何跨客户端连接服务器,7*24工作不是梦!
  5. Windows驱动中的inf文件
  6. Direct3D 12简介
  7. IBM IEEE 1394黄色感叹号
  8. 尤雨溪自述:打造Vue 3背后的故事
  9. 关于无法修改本地Hosts文件解决办法
  10. 速卖通代运营可靠吗?如何正确选择代运营?