我想研究解釋器和編譯器的基礎知識,使用F#和FsLexYacc庫,但是我很難理解編寫Lexer和Parser文件的原則......我正在關注this example,但它爲iterpreter使用了一些簡單的SQL查詢。我在尋找的是如何使用F#將this grammar轉換爲有效的Lexer和Parser。 如果有幫助,我會包含我的AST,Lexer和Parser文件。FsLexYacc。用F#和Leading分析和解析#
這是AST
module Ast
type TypeIdentifier =
|Boolean of bool
|Integer of int
|Float of float
|String of string
and BinaryOperators =
|Add
|Subtract
|Multiply
|Equal
|NotEqual
|Less
|Greater
|LessEqual
|GreaterEqual
|Semicolon
|Colon
|Range
|Assign
這是詞法
{
module SqlLexer
open System
open SqlParser
open Microsoft.FSharp.Text.Lexing
let keywords = [
"div", DIV;
"or", OR;
"and", AND;
"not", NOT;
"if", IF;
"then", THEN;
"else", ELSE;
"of", OF;
"while", WHILE;
"do", DO;
"array", ARRAY;
"procedure", PROCEDURE;
"program", PROGRAM;
"begin", BEGIN;
"end", END;
"var", VAR
] |> Map.ofList
let ops = [
"+", ADD;
"-", SUBTRACT;
"*", MULTIPLY;
"=", EQUAL;
"<>", NOTEQUAL;
"<", LESS;
"<=", LESSEQUAL;
">", GREATER;
">=", GREATEREQUAL;
":=", ASSIGN;
".", POINT;
",", COMMA;
";", SEMICOLON;
":", COLON;
"..", RANGE;
] |> Map.ofList
}
let char = ['a'-'z' 'A'-'Z']
let digit = ['0'-'9']
let int = '-'?digit+
let float = '-'?digit+ '.' digit+
let identifier = char(char|digit)*
let whitespece = [' ' '\t']
let newline = "\n\r" | '\n' | '\r'
let operator = "+" | "-" | "*" | "=" | "<>" | "<" | "<=" | ">" | ">=" | ":=" | "." | "," | ";" | ":" | ".."
rule tokenize = parse
| whitespace { tokenize lexbuf }
| newline { lexbuf.EndPos <- lexbuf.EndPos.NextLine; tokenise lexbuf; }
| int { INT(Int32.Parse(LexBuffer<_>.LexemeString lexbuf)) }
| float { FLOAT(Double.Parse(LexBuffer<_>.LexemeString lexbuf) }
| operator { ops.[LexBuffer<_>.LexemeString lexbuf] }
| identifier { match keywords.TryFind(LexBuffer<_>.LexemeString lexbuf) with
| Some(token) -> token
| None -> ID(LexBuffer<_>.LexemeString lexbuf)}
| eof { EOF }
這是我的解析器:
%{
open Sql
%}
%token <string> ID
%token <int> INT
%token <float> FLOAT
%token <bool> BOOL
%token DIV
%token AND OR NOT
%token IF THEN ELSE
%token WHILE DO
%token ARRAY OF
%token PROGRAM
%token PRODEDURE
%token BEGIN END
%token VAR
%token ADD SUBTRACT MULTIPLY
%token EQUAL NOTEQUAL
%token LESS LESSEQUAL
%token GREATER GREATEREQUAL
%token ASSIGN
%token POINT COMMA RANGE
%token SEMICOLON COLON
%start start
start:
PROGRAM ID ;
block .
EOF {
identifier = {$2}
block = {$4}
}
block:
|variableDeclarationPart procedureDeclaretionPart statementPart {$1, $2, $3}
variableDeclarationPart:
| {}
|VAR variableDeclaration ; {variableDeclaration;} {}
我不寫代碼尋找一個答案,我會像一些類似的例子的解釋或者使用FsLexYacc庫來解釋編程語言的教程帕斯卡