2013-11-05 30 views
5

我试图复活一个老F#解析器项目我已经工作在VS 2008与2013年VS工作它使用FsLexYacc。使用FsLex/yacc和Vs2013

我把它建设好通过使用预生成步骤为这样的:

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的解决方案一盏灯,如果是的话,怎么样?

回答

7

我不认为这些工具在默认情况下与安装有Visual Studio和这样的任务不存在F#编译器包括在内。我使用Visual Studio 2012项目完成了以下工作,但我预计它在VS 2013中会类似。以下是我必须遵循的步骤:

  1. 从nuget安装FSharp.Powerpack。这有fslex和fsyacc工具以及构建任务和目标。
  2. 卸载项目并编辑.fsproj文件。
  3. 为FSharp.Powerpack.target文件添加一条导入语句。这将添加CallFsLexCallFsYacc构建目标。我加入这个进口后Microsoft.FSharp.targets
    <Import Project="$(ProjectDir)\..\packages\FSPowerPack.Community.3.0.0.0\Tools\FSharp.PowerPack.targets" />

  4. 在文件的顶部添加这三种属性主要的PropertyGroup: <FsYaccToolPath>..\packages\FSPowerPack.Community.3.0.0.0\Tools</FsYaccToolPath> <FsLexToolPath>..\packages\FSPowerPack.Community.3.0.0.0\Tools</FsLexToolPath> <FsLexUnicode>true</FsLexUnicode>这告诉构建任务在哪里可以找到所需的工具,并为unicode的选项fslex。

  5. 要使用我们已经导入了目标,你需要与输入文件使用定义FsLex和FsYacc项目组。您还需要为输出.fs文件添加编译项目。你结束了在的ItemGroup节是这样的:
    <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" />

您可能能够使用FsLex和FsYacc直接引用FSharp.Powerpack.Build.Tasks.dll建设任务,但对我来说这很容易。

+1

谢谢你的麦克风。唉,我仍然无法工作。构建完全忽略了lex/yacc输入。我试着直接引用FSharp.Powerpack.Build.Tasks.dll,但仍然没有雪茄。 – stephensong

+0

这似乎符合我的经验 – nicolas

+0

@stephensong你没有任何错误? – nicolas

1

这对我来说是什么在起作用(Windows 7的64位时,Visual Studio 2013 RTM旗舰版):

  1. 获取并安装 “的PowerPack为FSharp 3.0 + .NET 4.x版+ VS2012” 从CodePlex上(https://fsharppowerpack.codeplex.com/downloads/get/625449

  2. 创建以下注册表项:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\AssemblyFolders\FSharp.PowerPack-1.9.9.9(适用于Windows的64位版本,省略Wow6432Node为32位版本)和它的(Default)值设置为F#PowerPack中的安装目录(如“C:\ Program Files文件(86 )\ FSharpPowerPack-4.0.0.0 \ BIN“)。 [这是关系到src/FSharp.PowerPack/CompilerLocationUtils.fs一个长期/回归的错误,基本上打破工具发现。]

  3. 导入PowerPack的目标(后导入F#的目标)在* .fsproj文件:<Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\FSharp.PowerPack.targets" />

  4. 更新您ItemGroup节点这样的事情(使用FsYacc相应):

    <ItemGroup> 
        <None Include="App.config" /> 
        <FsLex Include="Lexer.fsl" /> 
        <Compile Include="Lexer.fs"> 
        <Visible>False</Visible> 
        </Compile> 
        <Compile Include="Program.fs" /> 
    </ItemGroup> 
    
  5. 包括对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在麦克ž的回答说明。

: -

+1

谢谢。只是略读你的答案让人意识到为什么Fsharp.Powerpack正在被抛弃 - 是的?真正的巴洛克式,甚至奇怪。我发现F#由于像这样的愚蠢问题而继续萎靡不振。显然,M $对F#根本就不认真。 – stephensong

+0

F#PowerPack已从CodePlex转移到GitHub(https:// github。com/fsharp/powerpack),但即使没有太多的活动。现在大多数功能都是在不同的项目中开发的,而FsYacc和FsLex似乎被放弃了(尽管它们可能仍然用于F#编译器本身,但它仍然会得到更新)。虽然我还没有在任何地方发现官方声明,但微软目前似乎将更多精力投入到C++/Win8中,而不是整合到.Net中。 – JPW

1

这看起来像它的工作原理,至少在我的经验,如果使用单独的FsLexYacc NuGet包的详细here,然后把你的fsproj文件中的以下(从GitHub的example提取)接下来的所有其他进口:

<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包之外,不需要执行任何操作。