问题描述
我正在尝试在 F# 中设置一个新项目。
我使用 fslexYacc 作为工具,上次我使用它是在 Fsharp powerpack 'in' 的时候。网站上的文档不是那么好。在我看来,泛型类型注释 'end 也有一个错误,因为它是一个关键字..
但我首先只是从页面复制粘贴虚拟文件,以确保生成文件已启动并正在运行。 (词法分析器、解析器和程序)
页面: https://fsprojects.github.io/FsLexYacc/index.html
然后我得到
../../FSharp/Project/src/Lexer.fsl(21,81):错误 FS0001:“char”类型与“byte”类型不匹配
尝试通过将 _ 更改为根本没有帮助的字节来强制执行类型
Makefile:
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
解决方法
我试过了,但我无法重现您的错误。这就是我正在做的事情。有什么我做的和你不一样的吗?
我从存储库复制了 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"