Syntax checker

题目

Syntax checker

In a certain programming language (Ada) identifiers are defined by the syntax diagram (railroad chart) opposite. Transform the syntax diagram into a system of syntax diagrams which do not contain loops; i.e. which are purely recursive. Using these modified diagrams, write a predicate identifier/1 that can check whether or not a given string is a legal identifier.

% identifier(Str) :- Str is a legal identifier

解题

确定有限状态自动机或确定有限自动机(英语:deterministic finite automaton, DFA)是很有力的语法解析工具。

确定有限状态自动机

在计算理论中,确定有限状态自动机或确定有限自动机(英语:deterministic finite automaton, DFA)是一个能实现状态转移的自动机。对于一个给定的属于该自动机的状态和一个属于该自动机字母表的字元,它都能根据事先给定的转移函式转移到下一个状态(这个状态可以是先前那个状态)。

定义

确定有限状态自动机是由

  • 一个非空有限的状态集合
  • 一个输入字母表(非空有限的字元集合)
  • 一个转移函式(例如:
  • 一个开始状态
  • 一个接受状态的集合

所组成的5-元组。因此一个DFA可以写成这样的形式:

工作方式(非正式的语意)

确定有限状态自动机从起始状态开始,一个字元接一个字元地读入一个字串(这里的 指示Kleene星号算子。),并根据给定的转移函式一步一步地转移至下一个状态。在读完该字串后,如果该自动机停在一个属于F的接受状态,那么它就接受该字串,反之则拒绝该字串。

工作方式(正式的语意)

对于一个确定有限状态自动机,如果,我们就说该自动机接受字串w,反之则表明该自动机拒绝字串w。

被一个确定有限自动机接受的语言(或者叫「被辨识的语言」)定义为:,也就是由所有被接受的字串组成的集合。

用DFA对标识符语法建模

  • 一个非空有限的状态集合
  • 一个输入字母表,其中letter是英文字母集合,digit是数字集合
  • 一个转移函式
INITIALIZED LETTER HYPHEN DIGIT INVALID
letter LETTER LETTER LETTER LETTER INVALID
hyphen INVALID HYPHEN INVALID HYPHEN INVALID
digit INVALID DIGIT DIGIT DIGIT INVALID
other INVALID INVALID INVALID INVALID INVALID
  • 一个开始状态
  • 一个接受状态的集合

代码实现

INITIALIZED = 'INITIALIZED' LETTER = 'LETTER' HYPHEN = 'HYPHEN' DIGIT = 'DIGIT' INVALID = 'INVALID' def identifier(expr): syntaxChecker = DFA(syntaxDfaTransition, INITIALIZED, set([LETTER, DIGIT])) for s in expr: syntaxChecker.input(s) return syntaxChecker.isAcceptable() class DFA: def __init__(self, transition, startState, acceptStates): self.transition = transition self.state = startState self.acceptStates = acceptStates def input(self, s): self.state = self.transition(self.state, s) def isAcceptable(self): return self.state in self.acceptStates def syntaxDfaTransition(state, event): if state == INITIALIZED and isLetter(event): return LETTER if state == INITIALIZED and isHyphen(event): return INVALID if state == INITIALIZED and isDigit(event): return INVALID if state == INITIALIZED and isOther(event): return INVALID if state == LETTER and isLetter(event): return LETTER if state == LETTER and isHyphen(event): return HYPHEN if state == LETTER and isDigit(event): return DIGIT if state == LETTER and isOther(event): return INVALID if state == HYPHEN and isLetter(event): return LETTER if state == HYPHEN and isHyphen(event): return INVALID if state == HYPHEN and isDigit(event): return DIGIT if state == HYPHEN and isOther(event): return INVALID if state == DIGIT and isLetter(event): return LETTER if state == DIGIT and isHyphen(event): return HYPHEN if state == DIGIT and isDigit(event): return DIGIT if state == DIGIT and isOther(event): return INVALID if state == INVALID and isLetter(event): return INVALID if state == INVALID and isHyphen(event): return INVALID if state == INVALID and isDigit(event): return INVALID if state == INVALID and isOther(event): return INVALID def isLetter(event): return event.isalpha() def isHyphen(event): return event == '-' def isDigit(event): return event.isdigit() def isOther(event): return not (isLetter(event) or isHyphen(event) or isDigit(event))

参考

results matching ""

    No results matching ""