2013-11-05 63 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包之外,不需要執行任何操作。