0

我正在尝试在 F# 中设置一个新项目。

我使用 FsLexYacc 作为工具,上次我使用它是在 Fsharp 电源组“进入”时。网站上的文档不是很好。在我看来,泛型类型注释 'end 因为它是一个关键字..

但我首先只是从页面复制粘贴虚拟文件以确保生成文件已启动并运行。(词法分析器、解析器和程序)

页面: https ://fsprojects.github.io/FsLexYacc/index.html

然后我得到

../../FSharp/Project/src/Lexer.fsl(21,81):错误 FS0001:“char”类型与“byte”类型不匹配

试图通过将 _ 更改为根本没有帮助的字节来强制执行类型

生成文件:

OS=$(shell uname -s)
ifeq ($(OS),Darwin)
  export AS=as -arch i386
  export CC=cc -arch i386 -framework CoreFoundation -lobjc -liconv
endif

.PHONY: all clean

fsl = fslex
fsp = fsyacc
fsc = fsharpc --nologo

fsyacclib = FsLexYacc.10.2.0/build/fsyacc/netcoreapp3.1/FsLexYacc.Runtime.dll

Main = bin/Main.exe

LexerGen    = src/Lexer.fs
ParserGen   = src/Parser.fs

Lexer       = bin/Lexer.dll
Parser      = bin/Parser.dll    


all: $(Main)

$(LexerGen): src/Lexer.fsl 
    $(fsl) src/Lexer.fsl -o $(LexerGen)

$(ParserGen): src/Parser.fsy
    $(fsp) -v --module Parser src/Parser.fsy -o $(ParserGen)

$(Lexer):  $(LexerGen) $(Parser) 
    $(fsc) -a $(LexerGen) -r $(Parser) -o $(Lexer)

$(Parser): $(ParserGen) $(Regex) $(fsyacclib)
    $(fsc) -a $(ParserGen) -r $(Regex) -r $(fsyacclib) -o $(Parser) 

$(Main): src/Main.fsx $(Lexer) $(Parser) 
    $(fsc) -a src/Main.fsx -r $(fsyacclib)  -r $(Lexer) -r $(Parser) -o $(Main)


clean: rm /bin/*.dll 
4

1 回答 1

1

我试过这个,但我无法重现你的错误。这就是我正在做的事情。有什么我做的和你不一样的吗?

我从存储库中复制了Lexer.fsl文件:

{

// Opens methods related to fslex.exe
open FSharp.Text.Lexing

let newline (lexbuf: LexBuffer<_>) = 
  lexbuf.StartPos <- lexbuf.StartPos.NextLine

}

// Regular expressions
let whitespace = [' ' '\t' ]
let newline = ('\n' | '\r' '\n')

rule tokenstream = parse
// --------------------------
| "hello"       { Parser.HELLO }
// --------------------------
| whitespace    { tokenstream lexbuf }
| newline   { newline lexbuf; tokenstream lexbuf }
// --------------------------
| _         { failwith ("ParseError" + LexBuffer<_>.LexemeString lexbuf) }
| eof       { Parser.EOF }

Parser.fsy文件:

%{


%}

// The start token becomes a parser function in the compiled code:
%start start

// Regular tokens
%token HELLO

// Misc tokens
%token EOF

// This is the type of the data produced by a successful reduction of the 'start'
// symbol:
%type < int > start

%%

// These are the rules of the grammar along with the F# code of the 
// actions executed as rules are reduced.  
start: File end { $1 }
     | end      { $1 }

File:
    | HELLO                     { 1 }
    | HELLO HELLO               { 2 }


// Using F# keywords for nonterminal names is okay.
end: EOF { 3 }

并运行以下命令来编译这两个:

fsc Parser.fs Lexer.fs -r C:\[my work folder]\FsLexYacc\src\FsLexYacc.Runtime\bin\Debug\netstandard2.0\FsLexYacc.Runtime.dll

生成的源代码Lexer.fs如下所示:

module Lexer
# 1 "Lexer.fsl"
 

// Opens methods related to fslex.exe
open FSharp.Text.Lexing

let newline (lexbuf: LexBuffer<_>) = 
  lexbuf.StartPos <- lexbuf.StartPos.NextLine


# 12 "Lexer.fs"
let trans : uint16[] array = 
    [| 
    (* State 0 *)
     [| 5us;5us;5us;5us; (* lots more here... *)|];
    (* lots more states here... *)
    (* State 11 *)
     [| 65535us;65535us;65535us; (* lots more here... *)|];
    |] 
let actions : uint16[] = [|65535us;3us;1us;2us;3us;3us;4us;2us;65535us;65535us;65535us;0us;|]
let _fslex_tables = FSharp.Text.Lexing.UnicodeTables.Create(trans,actions)
let rec _fslex_dummy () = _fslex_dummy() 
// Rule tokenstream
and tokenstream  lexbuf =
  match _fslex_tables.Interpret(0,lexbuf) with
  | 0 -> ( 
# 17 "Lexer.fsl"
                             Parser.HELLO 
# 49 "Lexer.fs"
          )
  | 1 -> ( 
# 19 "Lexer.fsl"
                              tokenstream lexbuf 
# 54 "Lexer.fs"
          )
  | 2 -> ( 
# 20 "Lexer.fsl"
                           newline lexbuf; tokenstream lexbuf 
# 59 "Lexer.fs"
          )
  | 3 -> ( 
# 22 "Lexer.fsl"
                          failwith ("ParseError" + LexBuffer<_>.LexemeString lexbuf) 
# 64 "Lexer.fs"
          )
  | 4 -> ( 
# 23 "Lexer.fsl"
                          Parser.EOF 
# 69 "Lexer.fs"
          )
  | _ -> failwith "tokenstream"

# 3000000 "Lexer.fs"
于 2021-05-01T00:36:58.710 回答