나는 F # 및 FsLexYacc 라이브러리를 사용하여 통역사 및 컴파일러의 기초를 배우려고 노력하고 있지만 Lexer 및 Parser 파일을 작성하는 원칙을 이해하는 데 어려움을 겪고 있습니다 ... this example, 하지만 iterpreter에 대한 몇 가지 간단한 SQL 쿼리를 사용합니다. 내가 뭘 찾고 있는데, F #을 사용하여 작동하는 Lexer와 Parser로 this grammar을 변환하는 방법입니다. 도움이 필요하면 AST, Lexer 및 Parser 파일을 포함시킵니다. 내가 것,FsLexYacc. Lexing and Farsing with F #
%{
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;} {}
내가 작성한 코드로 답을 찾고 있지 않다 :
이
는 ASTmodule 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 }
렉서
입니다 그리고 이것은 내 파서이다 유사한 예제로 된 설명이나 FsLexYacc 라이브러리를 사용하여 프로그래밍 언어를 해석하는 튜토리얼 파스칼