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
399 声望102 粉丝

网络安全;函数式编程;数字货币;人工智能


引用和评论

0 条评论