5

vs 2008 で作業していた古い f# パーサー プロジェクトを、vs 2013 で作業するために復活させようとしています。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 ソリューションに適切に統合することが実際に可能かどうか、また可能であれば、その方法を明らかにできる人はいますか?

4

3 に答える 3

8

これらのツールは、Visual Studio と共にインストールされる F# コンパイラに既定で含まれているとは思わないため、タスクは存在しません。Visual Studio 2012 プロジェクトで次のことを行いましたが、VS 2013 でも同様になると思います。従わなければならなかった手順は次のとおりです。

  1. nuget から FSharp.Powerpack をインストールします。これには fslex ツールと fsyacc ツール、およびビルド タスクとターゲットがあります。
  2. プロジェクトをアンロードし、.fsproj ファイルを編集します。
  3. FSharp.Powerpack.target ファイルのインポート ステートメントを追加します。CallFsLexこれにより、CallFsYaccビルド ターゲットが追加されます。のインポート後にこれを追加しましたMicrosoft.FSharp.targets
    <Import Project="$(ProjectDir)\..\packages\FSPowerPack.Community.3.0.0.0\Tools\FSharp.PowerPack.targets" />

  4. これらの 3 つのプロパティをファイルの先頭にあるメインの 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 オプションが設定されます。

  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" />

FSharp.Powerpack.Build.Tasks.dll を参照することで、FsLex および FsYacc ビルド タスクを直接使用できるかもしれませんが、私にとっては、この方が簡単に作業を進めることができました。

于 2013-11-05T08:48:05.613 に答える
1

これは私にとってうまくいくものです(Windows 7 x64、Visual Studio 2013 Ultimate RTM):

  1. CodePlex ( https://fsharppowerpack.codeplex.com/downloads/get/625449 )から「PowerPack for FSharp 3.0 + .NET 4.x + VS2012」を入手してインストールします。

  2. 次のレジストリ キーを作成します: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\AssemblyFolders\FSharp.PowerPack-1.9.9.9(x64 バージョンの Windows の場合、Wow6432Node32 ビット バージョンの場合は省略します)、その(Default)値を F# PowerPack のインストール ディレクトリに設定します (例: "C:\Program Files (x86)\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注: mike z の回答で説明されているように適切なキーを指定すると、レジストリ キーの作成を省略できる可能性があります。

于 2013-11-11T11:59:17.507 に答える
1

これは機能しているように見えます-少なくとも、私の経験では、ここで詳しく説明されているように別の FsLexYacc nuget パッケージを使用し、fsproj ファイルに次のコードを記述した場合 (github のから抽出):

他のすべてのインポートの次に:

<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 パッケージをインストールする以外に何もする必要はありません。

于 2015-02-16T11:06:30.320 に答える