您需要的信息是在the documentation which comes with SML各地提供。很多university courses have online notes which contain working examples。
從你的示例代碼首先要注意的事情是,你已超負荷名稱alpha
,並用它來命名狀態和模式。這可能不是一個好主意。 alphanum
的模式沒有被定義,並且結果ID
未被聲明。在考慮使用狀態之前,您應該先解決一些基本錯誤 - 或者在SO上發佈一個問題。尋求有明顯缺陷的代碼的幫助並不能鼓勵專家的幫助。 :-)
修正了這些錯誤後,我們可以開始使用狀態。這裏是我的版本的代碼:
datatype lexresult = ID
| EOF
val error = fn x => TextIO.output(TextIO.stdOut,x^"\n")
val eof = fn() => EOF
%%
%structure myLang
digit=[0-9];
ws=[\ \t\n];
str=\"[.*]+\";
strop=\[[0-9...?\^]\];
%s ALPHA_STATE;
alpha=[a-zA-Z];
alphanum=[a-zA-Z0-9];
%%
<INITIAL>{alpha} => (YYBEGIN ALPHA_STATE; continue());
<ALPHA_STATE>{alphanum}+ => (YYBEGIN INITIAL; TextIO.output(TextIO.stdOut,"ID\n"); ID);
. => (error ("myLang: ignoring bad character "^yytext); lex());
你可以看到我已經添加ID
到lexresult
,命名爲國家ALPHA_STATE
並添加alphanum
模式。現在,讓我們來看看國家代碼是如何工作的:
有此計劃兩種狀態,他們被稱爲INITIAL
和ALPHA_STATE
(所有程序法有一個INITIAL
默認狀態)。它始終開始識別INITIAL
狀態。有一個規則<INITIAL>{alpha} =>
表示如果遇到處於初始狀態的信件(即不在ALPHA_STATE
中),則它是匹配並且應該調用該動作。這一規則的動作原理如下:
YYBEGIN ALPHA_STATE; (* Switch from INITIAL state to ALPHA_STATE *)
continue() (* and keep going *)
現在我們在ALPHA_STATE
它使這個狀態定義的那些規則,使規則<ALPHA_STATE>{alphanum} =>
。對此規則的操作切換回INITIAL
狀態並記錄匹配。
有關使用狀態(lex而不是ML-lex)的更長示例,您可以在此處看到我的答案:Error while parsing comments in lex。
爲了測試這個ML-LEX程序我引用這是很有幫助的問題:building a lexical analyser using ml-lex,並生成以下SML程序:
use "states.lex.sml";
open myLang
val lexer =
let
fun input f =
case TextIO.inputLine f of
SOME s => s
| NONE => raise Fail "Implement proper error handling."
in
myLang.makeLexer (fn (n:int) => input TextIO.stdIn)
end
val nextToken = lexer();
,只是爲了完整性,它產生以下輸出演示比賽:
c:\Users\Brian>"%SMLNJ_HOME%\bin\sml" main.sml
Standard ML of New Jersey v110.78 [built: Sun Dec 21 15:52:08 2014]
[opening main.sml]
[opening states.lex.sml]
[autoloading]
[library $SMLNJ-BASIS/basis.cm is stable]
[autoloading done]
structure myLang :
sig
structure UserDeclarations : <sig>
exception LexError
structure Internal : <sig>
val makeLexer : (int -> string) -> unit -> Internal.result
end
val it =() : unit
hello
ID