LoginSignup
5
1

More than 3 years have passed since last update.

TeX で LR(0) DFA のような強そうなオートマトンを描く

Last updated at Posted at 2019-05-17

レポート等でオートマトンを描きたくなることがあると思います。「TeX オートマトン」でググると、TikZのautomataライブラリでオートマトンを描く方法が様々な記事で解説されています。
それらの例で登場するオートマトンはどれも丸に矢印が生えているだけのシンプルな図です。では、以下のような状態遷移図はautomataライブラリで描くことができるでしょうか?

IMG_0168.jpg

これは ANDREW W. APPEL, Modern Compiler Implementation in ML という本に出てくる、LR(0) DFA と呼ばれるオートマトンです。このオートマトンは

\begin{align}
S &\rightarrow E \$ \\
E &\rightarrow T \\ 
E &\rightarrow T + E \\
T &\rightarrow x
\end{align}

という言語に対応していて、LR(0) の場合 shift と reduce が衝突して解析できませんが、 SLR (Simple LR(1)) の場合解析できます。

さて、これを描いてみましょう。

\usepackage{tikz}

\usetikzlibrary{automata}

\begin{tikzpicture}
  [>=latex, 
    node distance=3cm, 
    block/.style={state, rectangle, text width=6em}
  ]

  \node [block, label=above right:1] (q_0) 
    {
      \( S \rightarrow . E \$ \) \\
      \( E \rightarrow . T + E \) \\
      \( E \rightarrow . T \) \\
      \( T \rightarrow . x \) 
    };
  \node [block, label=above right:2] (q_1) [right of = q_0]
    {
      \( S \rightarrow E . \$ \)
    };
  \node [block, label=above right:3] (q_2) [below of = q_1] 
    {
      \( E \rightarrow T . + E \) \\
      \( E \rightarrow T . \)
    };
  \node [block, label=above right:4] (q_3) [below of = q_2]
    {
      \( E \rightarrow T + . E \) \\
      \( E \rightarrow . T + E \) \\
      \( E \rightarrow . T \) \\
      \( T \rightarrow . x \) 
    };
  \node [block, label=above right:5] (q_4) [left of = q_3]
    {
      \( T \rightarrow x . \)
    };
  \node [block, label=above right:6] (q_5) [right of = q_3]
    {
      \( E \rightarrow T + E . \)
    };

  \path [->] (q_0) edge [right]      node [above] {\(E\)} (q_1)
                   edge [right]      node [above] {\(T\)} (q_2)
                   edge [right]      node [left]  {\(x\)} (q_4)
             (q_2) edge [bend right] node [left]  {\(+\)} (q_3)
             (q_3) edge [right]      node [above] {\(x\)} (q_4)
                   edge [bend right] node [right] {\(T\)} (q_2)
                   edge [right]      node [above] {\(E\)} (q_5);
\end{tikzpicture}

すると

スクリーンショット 2019-05-17 21.34.43.png

それらしきものを描くことができました。

いくつかのポイント

  • node の style で rectangle を指定することで、状態の部分を四角形にすることができます。
  • node の style で text width を指定することで、中で改行ができるようになります。
  • 中で複数行の数式を書くとき、普通に align 環境を使うと、数式の上側に余白ができて不恰好になってしまうので、一行ずつ数式を分けて書くのが良いと思います(もしオートマトン以外で数式を使わないのであれば、グローバルなオプションで余白の大きさを変えてしまっても良いとは思いますが)。
5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1