Создание простого парсера в F#

В настоящее время я пытаюсь создать очень простой парсер в F#, используя FsLex и FsYacc. Во-первых, единственная функциональность, которую я пытаюсь достичь, - это позволить программе принимать строку, представляющую сложение целых чисел, и выводить результат. Например, я бы хотел, чтобы анализатор мог принимать "5 + 2" и выводить строку "7". Меня интересуют только строковые аргументы и выходные данные, потому что я хотел бы импортировать синтаксический анализатор в Excel с использованием Excel DNA, как только я расширю функциональность для поддержки большего количества операций. Тем не менее, я в настоящее время изо всех сил пытаюсь заставить даже это простое целочисленное дополнение работать правильно.

Мой файл lexer.fsl выглядит так:

{
module lexer
open System
open Microsoft.FSharp.Text.Lexing
open Parser

let lexeme = LexBuffer<_>.LexemeString

let ops = ["+", PLUS;] |> Map.ofList
}

let digit = ['0'-'9']
let operator = "+"
let integ = digit+

rule lang = parse
    | integ 
    {INT(Int32.Parse(lexeme lexbuf))}
    | operator 
    {ops.[lexeme lexbuf]}

Мой файл parser.fsy выглядит так:

%{
open Program
%}

%token <int>INT
%token PLUS

%start input
%type <int> input

%%

input: 
    exp {$1}
;

exp: 
    | INT { $1 }
    | exp exp PLUS { $1 + $2 }
;

Кроме того, у меня есть файл Program.fs, который действует как (очень маленький) AST:

module Program

type value = 
    | Int of int

type op = Plus

Наконец, у меня есть файл Main.fs, который должен проверить функциональность интерпретатора (а также импортировать функцию в Excel).

module Main

open ExcelDna.Integration
open System
open Program
open Parser

[<ExcelFunction(Description = "")>]
    let main () =
    let x = "5 + 2"
    let lexbuf = Microsoft.FSharp.Text.Lexing.LexBuffer<_>.FromString x
    let y = input lexer.lang lexbuf
    y

Однако когда я запускаю эту функцию, парсер вообще не работает. Когда я собираю проект, файлы parser.fs и lexer.fs создаются правильно. Я чувствую, что есть что-то простое, что мне не хватает, но я понятия не имею, как правильно сделать эту функцию.

0 ответов

Другие вопросы по тегам