我正在尝试恢复我在vs 2008中与vs 2013一起工作的旧f#解析器项目。它使用FsLexYacc。
我通过使用预建步骤得到了正确的结果:
fslex --unicode "$(ProjectDir)XpathLexer.fsl"
fsyacc --module XpathParser "$(ProjectDir)XpathParser.fsy"
但这不太理想,因为无论输入是否发生变化,它总是会执行。
然后我尝试使用旧的MsBuild操作:
<FsYacc Include="XpathParser.fsy">
<FsLex Include="XpathLexer.fsl">
但在构建过程中似乎完全忽略了这些。是对的吗?是否以某种方式删除了这些构建任务?
然后我发现了一些我认为可能有效的vs C ++文档:
<CustomBuild Include="XpathParser.fsy">
<Message>Calling FsYacc</Message>
<Command>fsyacc --module XpathParser "$(ProjectDir)XpathParser.fsy"</Command>
<Outputs>$(ProjectDir)XpathParser.fs</Outputs>
</CustomBuild>
和
<PropertyGroup>
<CustomBuildBeforeTargets>CoreCompile</CustomBuildBeforeTargets>
</PropertyGroup>
(我检查了Microsoft.Fsharp.Targets文件以提出“CoreCompile”目标。)
唉,还是没有雪茄。是否有人能够确定是否确实可以将fslex / yacc正确地集成到vs 2013解决方案中,如果是,如何?
答案 0 :(得分:7)
我不认为这些工具默认包含在随Visual Studio一起安装的F#编译器中,因此任务不存在。我使用Visual Studio 2012项目执行了以下操作,但我希望它在VS 2013中类似。以下是我必须遵循的步骤:
为FSharp.Powerpack.target文件添加import语句。这将添加CallFsLex
和CallFsYacc
构建目标。我在导入Microsoft.FSharp.targets
后添加了这个:
<Import Project="$(ProjectDir)\..\packages\FSPowerPack.Community.3.0.0.0\Tools\FSharp.PowerPack.targets" />
将这三个属性添加到文件顶部的主PropertyGroup:
<FsYaccToolPath>..\packages\FSPowerPack.Community.3.0.0.0\Tools</FsYaccToolPath>
<FsLexToolPath>..\packages\FSPowerPack.Community.3.0.0.0\Tools</FsLexToolPath>
<FsLexUnicode>true</FsLexUnicode>
这告诉构建任务在哪里找到必要的工具并为fslex设置unicode选项。
<Compile Include="Sql.fs" />
<FsYacc Include="SqlParser.fsp">
<Module>SqlParser</Module>
</FsYacc>
<Compile Include="SqlParser.fsi" />
<Compile Include="SqlParser.fs" />
<FsLex Include="SqlLexer.fsl" />
<Compile Include="SqlLexer.fs" />
您可以通过引用FSharp.Powerpack.Build.Tasks.dll直接使用FsLex和FsYacc构建任务,但对我来说这更容易开始。
答案 1 :(得分:1)
这对我有用(Windows 7 x64,Visual Studio 2013 Ultimate RTM):
从CodePlex获取并安装“PowerPack for FSharp 3.0 + .NET 4.x + VS2012”(https://fsharppowerpack.codeplex.com/downloads/get/625449)
创建以下注册表项:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\AssemblyFolders\FSharp.PowerPack-1.9.9.9
(对于x64版本的Windows,省略32位版本的Wow6432Node
)并将其(Default)
值设置为安装目录F#PowerPack(例如“C:\ Program Files(x86)\ FSharpPowerPack-4.0.0.0 \ bin”)。 [这与src/FSharp.PowerPack/CompilerLocationUtils.fs
中的长期/回归错误有关,它基本上会破坏工具发现。]
在* .fsproj文件中导入PowerPack目标(导入F#目标后):<Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\FSharp.PowerPack.targets" />
将ItemGroup
节点更新为此类节点(相应地使用FsYacc):
<ItemGroup>
<None Include="App.config" />
<FsLex Include="Lexer.fsl" />
<Compile Include="Lexer.fs">
<Visible>False</Visible>
</Compile>
<Compile Include="Program.fs" />
</ItemGroup>
包括对FSharp.PowerPack.dll
和构建的引用。
你应该得到一个与此类似的* .fsproj文件:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>8c565f99-d6bc-43a9-ace9-eadfe429c0f7</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>FsYaccTest</RootNamespace>
<AssemblyName>FsYaccTest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFSharpCoreVersion>4.3.1.0</TargetFSharpCoreVersion>
<Name>FsYaccTest</Name>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<!-- Snip -->
</PropertyGroup>
<ItemGroup>
<Reference Include="FSharp.PowerPack">
<HintPath>C:\Program Files (x86)\FSharpPowerPack-4.0.0.0\bin\FSharp.PowerPack.dll</HintPath>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
</ItemGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '11.0'">
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" />
<Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\FSharp.PowerPack.targets" />
<PropertyGroup>
<FsLexUnicode>true</FsLexUnicode>
</PropertyGroup>
<ItemGroup>
<None Include="App.config" />
<FsLex Include="Lexer.fsl" />
<Compile Include="Lexer.fs">
<Visible>False</Visible>
</Compile>
<Compile Include="Program.fs" />
</ItemGroup>
</Project>
注意:如果你提供正确的FsYaccToolPath
,你可以省略创建注册表项,如mike z的回答所述。
答案 2 :(得分:1)
这看起来很有效 - 至少,根据我的经验,如果你使用单独的FsLexYacc nuget包作为详细的here,然后将以下内容放在你的fsproj文件中(从github {{3}中提取) }):
在所有其他导入旁边:
<Import Project="..\packages\FsLexYacc.6.0.4\bin\FsLexYacc.targets" />
等等
然后是源文件:
<FsYacc Include="Parser.fsp">
<OtherFlags>--module SqlParser</OtherFlags>
</FsYacc>
<FsLex Include="Lexer.fsl">
<OtherFlags>--unicode</OtherFlags>
</FsLex>
除编辑fsproj文件外,无需执行任何操作,并安装nuget软件包。