2015-02-11 43 views
0

我建立在ML-萊克斯一個tokeniser定義的,其中的一部分是如何在ML-Lex中使用開始狀態?

datatype lexresult = STRING 
        | STRINGOP 
        | 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; 
alpha=[a-zA-Z]; 
%% 

<alpha> {alphanum}+ => (ID); 
. => (error ("myLang: ignoring bad character "^yytext); lex()); 

我想,只有當它與啓動或「阿爾法」後發現該類型ID應被檢測到。我知道,寫它作爲

{alpha}+ {alphanum}* => (ID); 

是一種選擇,但我需要學習使用從使用開始的狀態,以及一些其他的目的。有人可以幫助我嗎?

回答

0

您需要的信息是在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()); 

你可以看到我已經添加IDlexresult,命名爲國家ALPHA_STATE並添加alphanum模式。現在,讓我們來看看國家代碼是如何工作的:

有此計劃兩種狀態,他們被稱爲INITIALALPHA_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