首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Vs2013中使用FsLex/Yacc

在Vs2013中使用FsLex/Yacc
EN

Stack Overflow用户
提问于 2013-11-05 10:53:11
回答 3查看 1.5K关注 0票数 5

我正在尝试恢复一个旧的f#解析器项目,该项目是我在VS2008中工作的,用于VS2013。它使用FsLexYacc。

我通过使用预构建步骤让它构建正常,如下所示:

代码语言:javascript
复制
fslex --unicode "$(ProjectDir)XpathLexer.fsl"
fsyacc --module XpathParser "$(ProjectDir)XpathParser.fsy"

但这并不理想,因为无论输入是否更改,它都会执行。

然后,我尝试只使用旧的MsBuild操作:

代码语言:javascript
复制
<FsYacc Include="XpathParser.fsy">
<FsLex Include="XpathLexer.fsl">

但在构建过程中,这些似乎被完全忽略了。是那么回事吗?是否以某种方式删除了这些构建任务?

然后我在vs C++下找到了一些我认为可能有用的东西:

代码语言:javascript
复制
<CustomBuild Include="XpathParser.fsy">
  <Message>Calling FsYacc</Message>
  <Command>fsyacc --module XpathParser "$(ProjectDir)XpathParser.fsy"</Command>
  <Outputs>$(ProjectDir)XpathParser.fs</Outputs>
</CustomBuild>

代码语言:javascript
复制
<PropertyGroup>
    <CustomBuildBeforeTargets>CoreCompile</CustomBuildBeforeTargets>
</PropertyGroup>

(我检查了Microsoft.Fsharp.Targets文件,找到了"CoreCompile“目标。)

可惜,还是没有雪茄。

有没有人能够阐明是否真的有可能将fslex/yacc正确地集成到vs 2013解决方案中,如果是,如何集成?

EN

回答 3

Stack Overflow用户

发布于 2013-11-05 16:48:06

我不认为这些工具默认情况下包含在随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. Add之后,我将这三个属性添加到文件顶部的main 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构建任务,但对我来说,这更容易上手。

票数 8
EN

Stack Overflow用户

发布于 2013-11-11 19:59:18

这就是我的工作(Windows7 x64,Visual Studio2013旗舰版):

  1. 从CodePlex
  2. 获取并安装以下注册表项"PowerPack FSharp 3.0 + .NET 4.x + VS2012“:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\AssemblyFolders\FSharp.PowerPack-1.9.9.9 (对于x64版本的Windows32位版本,忽略Wow6432Node ),并将其(Default)值设置为F# PowerPack的安装目录(例如"C:\Program Files (x86)\FSharpPowerPack-4.0.0.0\bin")。这与src/FSharp.PowerPack/CompilerLocationUtils.fs中一个长期存在的/回归错误有关,它基本上破坏了*.fsproj文件中PowerPack目标的工具(在导入F#目标之后):将ItemGroup节点<Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\FSharp.PowerPack.targets" />
  3. Update到如下所示的位置(相应地使用ItemGroup):

False

  • 包含对FSharp.PowerPack.dll和build的引用。

您应该会得到一个类似于下面这样的*.fsproj文件:

代码语言:javascript
复制
<?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的答案所述),则可以省略创建注册表项。

票数 1
EN

Stack Overflow用户

发布于 2015-02-16 19:06:30

这看起来是可行的--至少在我的经验中,如果你使用单独的FsLexYacc nuget包作为详细的here,然后在你的fsproj文件中放入以下内容(从github example中提取):

在所有其他导入的旁边:

代码语言:javascript
复制
<Import Project="..\packages\FsLexYacc.6.0.4\bin\FsLexYacc.targets" />

等等,等等

然后对于源文件:

代码语言:javascript
复制
<FsYacc Include="Parser.fsp">
  <OtherFlags>--module SqlParser</OtherFlags>
</FsYacc>
<FsLex Include="Lexer.fsl">
  <OtherFlags>--unicode</OtherFlags>
</FsLex>

除了编辑fsproj文件和安装nuget包之外,不需要做任何事情。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19781156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档