2013-11-05 10 views
5

Próbuję wskrzesić stary projekt parsera f #, w którym pracowałem vs 2008, aby pracować z vs 2013. Używa FsLexYacc.Używanie FsLex/Yacc w Vs2013

mam to budowę ok stosując krok prebuild jako sposób:

fslex --unicode "$(ProjectDir)XpathLexer.fsl" 
fsyacc --module XpathParser "$(ProjectDir)XpathParser.fsy" 

Ale to jest mniej niż idealna, jak to zawsze wykonuje czy wejścia uległy zmianie.

Następnie próbowałem tylko przy użyciu starych działania MSBuild:

<FsYacc Include="XpathParser.fsy"> 
<FsLex Include="XpathLexer.fsl"> 

ale to wydaje się być całkowicie ignorowane podczas procesu kompilacji. Czy to prawda? Czy te zadania budowania zostały jakoś usunięte?

I potem znaleźć jakiś materiał udokumentowana zgodnie vs C++, że pomyślałem, że może pracować:

<CustomBuild Include="XpathParser.fsy"> 
    <Message>Calling FsYacc</Message> 
    <Command>fsyacc --module XpathParser "$(ProjectDir)XpathParser.fsy"</Command> 
    <Outputs>$(ProjectDir)XpathParser.fs</Outputs> 
</CustomBuild> 

i

<PropertyGroup> 
    <CustomBuildBeforeTargets>CoreCompile</CustomBuildBeforeTargets> 
</PropertyGroup> 

(I sprawdzony plik Microsoft.Fsharp.Targets aby wymyślić " CoreCompile "target.)

Niestety, wciąż nie ma cygara.

Czy ktoś jest w stanie rzucić światło na to, czy rzeczywiście można właściwie włączyć fslex/yacc do rozwiązania vs 2013, a jeśli tak, to w jaki sposób?

Odpowiedz

7

Nie sądzę, że te narzędzia są domyślnie dołączone do kompilatora F # zainstalowanego w programie Visual Studio, więc zadania nie istnieją. Zrobiłem co następuje z projektem Visual Studio 2012, ale spodziewam się, że będzie podobny w VS 2013. Oto kroki, które musiałem wykonać:

  1. Zainstaluj FSharp.Powerpack od nuget. To ma narzędzia fslex i fsyacc, a także budować zadania i cele.
  2. Usuń projekt i edytuj plik .fsproj.
  3. Dodaj instrukcję importu dla pliku FSharp.Powerpack.target. Spowoduje to dodanie celów kompilacji i CallFsYacc. Dodałem to po imporcie do Microsoft.FSharp.targets:
    <Import Project="$(ProjectDir)\..\packages\FSPowerPack.Community.3.0.0.0\Tools\FSharp.PowerPack.targets" />

  4. Dodaj te trzy właściwości do głównej PropertyGroup na początku pliku: <FsYaccToolPath>..\packages\FSPowerPack.Community.3.0.0.0\Tools</FsYaccToolPath> <FsLexToolPath>..\packages\FSPowerPack.Community.3.0.0.0\Tools</FsLexToolPath> <FsLexUnicode>true</FsLexUnicode> Mówi zadania kompilacji, gdzie znaleźć potrzebne narzędzia i ustawia opcję Unicode fslex.

  5. Aby użyć zaimportowanych celów, musisz zdefiniować grupy elementów FsLex i FsYacc z plikami wejściowymi do użycia. Musisz także dodać elementy kompilacji dla wyjściowych plików .fs. Skończyć z czymś takim w sekcji 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" />

może być w stanie korzystać z FsLex i FsYacc budować zadań bezpośrednio przez odwołanie do FSharp.Powerpack.Build.Tasks.dll, ale dla mnie to było łatwiejsze.

+1

Dzięki za ten mikrofon. Niestety, nadal nie mogłem go uruchomić. Kompilacja całkowicie ignoruje dane wejściowe lex/yacc. Próbowałem odnieść się bezpośrednio do FSharp.Powerpack.Build.Tasks.dll, ale nadal nie ma cygara. – stephensong

+0

który wydaje się zgodny z moim doświadczeniem – nicolas

+0

@stephensong nie masz żadnych błędów? – nicolas

1

To, co działa dla mnie (Windows 7 x64, Visual Studio 2013 RTM):

  1. Pobierz i zainstaluj "PowerPack dla FSharp 3,0 + .NET 4.x + VS2012" od CodePlex (https://fsharppowerpack.codeplex.com/downloads/get/625449)

  2. Utwórz następujący klucz rejestru: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\AssemblyFolders\FSharp.PowerPack-1.9.9.9 (dla wersji x64 systemu Windows, należy pominąć Wow6432Node dla wersji 32-bitowych) i ustawić jej wartość (Default) do katalogu instalacyjnego F # PowerPack (np „C: Program Files \ (x86) \ FSharpPowerPack-4.0.0.0 \ bin "). [Jest to związane z błędem wieloletnie/regresji w src/FSharp.PowerPack/CompilerLocationUtils.fs które zasadniczo łamie odkrycie narzędzia.]

  3. importu cele PowerPack (Po zaimportowaniu F # cele) w * .fsproj pliku: <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\FSharp.PowerPack.targets" />

  4. aktualizacji węzeł do czegoś takiego ItemGroup (użyj FsYacc odpowiednio):

    <ItemGroup> 
        <None Include="App.config" /> 
        <FsLex Include="Lexer.fsl" /> 
        <Compile Include="Lexer.fs"> 
        <Visible>False</Visible> 
        </Compile> 
        <Compile Include="Program.fs" /> 
    </ItemGroup> 
    
  5. zawierać odniesienie do FSharp.PowerPack.dll i budować.

Należy skończyć z * .fsproj plik podobny do tego:

<?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> 

Uwaga: Można chyba należy pominąć tworzenia klucza rejestru, jeśli zapewniają właściwą FsYaccToolPath jak opisano w odpowiedzi mike Z. .

+1

Dzięki za to. Wystarczy przeskrobać swoją odpowiedź, aby uświadomić sobie, dlaczego Fsharp.Powerpack jest opuszczony - tak? Prawdziwie barokowy, dziwaczny. To smutne, że F # nadal marnieje z powodu głupich problemów takich jak ta. Najwyraźniej, M $ po prostu nie mówi poważnie o F #. – stephensong

+0

F # PowerPack został przeniesiony z CodePlex do GitHub (https: // github.com/fsharp/powerpack), ale nawet nie ma zbyt dużej aktywności. Większość funkcji jest teraz rozwijana w różnych projektach, podczas gdy FsYacc i FsLex wydają się być porzucone (chociaż prawdopodobnie są nadal używane w samym kompilatorze F #, który oczywiście wciąż otrzymuje aktualizacje). Chociaż nigdzie nie znalazłem oficjalnego oświadczenia, Microsoft wydaje się obecnie wkładać więcej wysiłku w C++/Win8 niż w .Net w ogóle. – JPW

1

To wygląda jak to działa - przynajmniej w moim doświadczeniu, w przypadku korzystania z oddzielnego pakietu FsLexYacc Nuget jak szczegółowe here, a następnie umieścić następujące informacje w pliku fsproj (wyciąg z github example):

obok wszystkich innych importu:

<Import Project="..\packages\FsLexYacc.6.0.4\bin\FsLexYacc.targets" /> 

etc, etc

a następnie do plików źródłowych:

<FsYacc Include="Parser.fsp"> 
    <OtherFlags>--module SqlParser</OtherFlags> 
</FsYacc> 
<FsLex Include="Lexer.fsl"> 
    <OtherFlags>--unicode</OtherFlags> 
</FsLex> 

Nie trzeba nic robić, oprócz edycji pliku fsproj i instalowania pakietów nuget.

Powiązane problemy