Recently, I was reading the book Compilation Principles, and it felt like a great introductory book (referring to the difficulty from shallow to deep). The first two chapters are mainly conceptual things, and the third chapter starts to get real, with formulas on the code. If you don't implement it yourself, you'll just see it in a fog. So I may occasionally update some articles about the implementation of what I saw in the book Principles of Compilation in the next period of time.

Chapter 3 of the book describes how DFA matches strings. For example, the regular expression (a|b)*abb can be converted to the following DFA code. Through the mechanism of the state machine, the current state is switched when the character is read, and whether the match is successful is determined according to the last state.

defmodule DFA do
  
  def init(string) do
    %{
      s: 0,
      chars: String.to_charlist(string)
    }
  end

  def run(%{s: s, chars: [h | t]}) do
    s = move(s, h)
    run(%{s: s, chars: t})
  end
  def run(%{s: s, chars: []}) do
    if s in f() do
      :yes
    else
      :no
    end
  end

  defp move(0, ?a), do: 1
  defp move(0, ?b), do: 0
  defp move(1, ?a), do: 1
  defp move(1, ?b), do: 2
  defp move(2, ?a), do: 1
  defp move(2, ?b), do: 3
  defp move(3, ?a), do: 1
  defp move(3, ?b), do: 0

  defp f(), do: [3]

end

This DFA will only match strings ending with "abb":

DFA.init("ababb")
|> DFA.run()

# :yes

DFA.init("ababa")
|> DFA.run()

# :no

Isn't it amazing?


Ljzn
407 声望103 粉丝

尽量减少神经质的时间


引用和评论

0 条评论