私は、F#とFsLexYaccライブラリを使って、インタプリタとコンパイラの基礎を勉強しようとしていますが、私はLexerとParserファイルを書く原則を理解するのに苦労しています... this example、 iterpreterのためのいくつかの簡単なSQLクエリを使用しています。私が探しているのは、this grammarをF#を使ってLexerとParserに変換する方法です。 ASTファイル、Lexerファイル、Parserファイルが含まれていれば、それらのファイルが含まれます。FsLexYacc。レキシングとFを使った解析#
これはこれは、レクサー
{
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 }
であり、これは私のパーサである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
です:
%{
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ライブラリを使ってプログラミング言語を解釈するチュートリアルなどパスカル