ओकैम की बात आती है जब मैं पूरी नौसिखिया हूं। मैंने हाल ही में भाषा का उपयोग शुरू कर दिया है (लगभग 2 सप्ताह पहले), लेकिन दुर्भाग्य से, मुझे एक सिंटैक्स विश्लेषक (पार्सर + लेक्सर, जिसका फ़ंक्शन या तो स्वीकार करने या वाक्य नहीं है) बनाने के लिए काम किया गया है मेनिर का उपयोग करना अब, मुझे ओकैमल और मेनिर के बारे में इंटरनेट पर कुछ सामग्री मिली है:ओकैमल + मेनिर संकलन/लेखन
मेनिर मैनुअल।
This webpage for some French University course.
Sourceforge पर टॉस के मुखपृष्ठ पर एक छोटी Menhir ट्यूटोरियल।
डेरडन द्वारा जिथब पर एक मेनिर उदाहरण।
A book on OCaml (with a few things about ocamllex+ocamlyacc
SooHyoung ओह द्वारा एक यादृच्छिक ocamllex ट्यूटोरियल।
और मेनिर के स्रोत कोड के साथ आने वाले उदाहरण।
(मैं दो से अधिक हाइपरलिंक नहीं डाल सकते, इसलिए मैं आपको वेबसाइटों मैं यहाँ यह उल्लेख कर रहा हूँ में से कुछ से सीधे लिंक नहीं कर सकते। क्षमा करें!)
तो, जैसा कि आप देख सकते हैं, मैं मैं इस कार्यक्रम के निर्माण में सहायता करने के लिए अधिक से अधिक सामग्री की तलाश कर रहा हूं। दुर्भाग्य से, मैं अभी भी कई अवधारणाओं को समझ नहीं सकता, और इस तरह, मुझे कई, कई कठिनाइयों का सामना करना पड़ रहा है।
स्टार्टर्स के लिए, मुझे नहीं पता कि मेरे प्रोग्राम को सही तरीके से कैसे संकलित किया जाए। मैं निम्नलिखित कमांड का उपयोग कर रहा हूं:
ocamlbuild -use-menhir -menhir "menhir --external-tokens Tokens" main.native
मेरा प्रोग्राम चार अलग-अलग फ़ाइलों में विभाजित है: main.ml; lexer.mll; parser.mly; tokens.mly। main.ml वह हिस्सा है जो तर्क के रूप में दिए गए फ़ाइल सिस्टम में फ़ाइल से इनपुट प्राप्त करता है।
let filename = Sys.argv.(1)
let() =
let inBuffer = open_in filename in
let lineBuffer = Lexing.from_channel inBuffer in
try
let acceptance = Parser.main Lexer.main lineBuffer in
match acceptance with
| true -> print_string "Accepted!\n"
| false -> print_string "Not accepted!\n"
with
| Lexer.Error msg -> Printf.fprintf stderr "%s%!\n" msg
| Parser.Error -> Printf.fprintf stderr "At offset %d: syntax error.\n%!" (Lexing.lexeme_start lineBuffer)
दूसरी फ़ाइल lexer.mll है।
{
open Tokens
exception Error of string
}
rule main = parse
| [' ' '\t']+
{ main lexbuf }
| ['0'-'9']+ as integer
{ INT (int_of_string integer) }
| "True"
{ BOOL true }
| "False"
{ BOOL false }
| '+'
{ PLUS }
| '-'
{ MINUS }
| '*'
{ TIMES }
| '/'
{ DIVIDE }
| "def"
{ DEF }
| "int"
{ INTTYPE }
| ['A'-'Z' 'a'-'z' '_']['0'-'9' 'A'-'Z' 'a'-'z' '_']* as s
{ ID (s) }
| '('
{ LPAREN }
| ')'
{ RPAREN }
| '>'
{ LARGER }
| '<'
{ SMALLER }
| ">="
{ EQLARGER }
| "<="
{ EQSMALLER }
| "="
{ EQUAL }
| "!="
{ NOTEQUAL }
| '~'
{ NOT }
| "&&"
{ AND }
| "||"
{ OR }
| '('
{ LPAREN }
| ')'
{ RPAREN }
| "writeint"
{ WRITEINT }
| '\n'
{ EOL }
| eof
{ EOF }
| _
{ raise (Error (Printf.sprintf "At offset %d: unexpected character.\n" (Lexing.lexeme_start lexbuf))) }
तीसरी फ़ाइल पार्सर.मी है।
%start <bool> main
%%
main:
| WRITEINT INT { true }
चौथे tokens.mly
%token <string> ID
%token <int> INT
%token <bool> BOOL
%token EOF EOL DEF INTTYPE LPAREN RPAREN WRITEINT
%token PLUS MINUS TIMES DIVIDE
%token LARGER SMALLER EQLARGER EQSMALLER EQUAL NOTEQUAL
%token NOT AND OR
%left OR
%left AND
%nonassoc NOT
%nonassoc LARGER SMALLER EQLARGER EQSMALLER EQUAL NOTEQUAL
%left PLUS MINUS
%left TIMES DIVIDE
%nonassoc LPAREN
%nonassoc ATTRIB
%{
type token =
| ID of (string)
| INT
| BOOL
| DEF
| INTTYPE
| LPAREN
| RPAREN
| WRITEINT
| PLUS
| MINUS
| TIMES
| DIVIDE
| LARGER
| SMALLER
| EQLARGER
| EQSMALLER
| EQUAL
| NOTEQUAL
| NOT
| AND
| OR
| EOF
| EOL
%}
%%
अब है, मुझे पता है कि यहां अप्रयुक्त प्रतीकों में से एक बहुत कुछ है, लेकिन मैं उन्हें अपने पार्सर में उपयोग करना चाहते हैं। कोई फर्क नहीं पड़ता कि मैं फ़ाइलों में कितने बदलाव करता हूं, संकलक मेरे चेहरे पर उड़ता रहता है। मैंने जो कुछ भी सोच सकता हूं उसकी कोशिश की है, और कुछ भी काम नहीं करता है। यह क्या है कि अनबाउंड कन्स्ट्रक्टर और गैर-परिभाषित प्रारंभ प्रतीकों की त्रुटियों में ओकम्बुबिल्ड विस्फोट कर रहा है? प्रोग्राम को ठीक से संकलित करने के लिए मुझे किस कमांड का उपयोग करना चाहिए? मेनिर के बारे में जानने के लिए मुझे सार्थक सामग्री कहां मिल सकती है?फिर, मैं जादू विकल्प नहीं जानते ocamlbuild
को पारित करने के लिए
%token <string> ID
%token <int> INT
%token <bool> BOOL
%token EOF EOL DEF INTTYPE LPAREN RPAREN WRITEINT
%token PLUS MINUS TIMES DIVIDE
%token LARGER SMALLER EQLARGER EQSMALLER EQUAL NOTEQUAL
%token NOT AND OR
%left OR
%left AND
%nonassoc NOT
%nonassoc LARGER SMALLER EQLARGER EQSMALLER EQUAL NOTEQUAL
%left PLUS MINUS
%left TIMES DIVIDE
%nonassoc LPAREN
%nonassoc ATTRIB
%%
और मैं बहुत अच्छी तरह से menhir
पता नहीं है,:
दरअसल, केवल एक 'mly' होने से बहुत आसान है। मैंने अपने जवाब में उस समाधान का प्रस्ताव नहीं दिया है क्योंकि मैं मान रहा था कि @ लोप्सन मेनिर की "पार्सिंग इकाइयों के अलग संकलन" का उपयोग करना चाहता था। – Thomas
सभी मदद के लिए धन्यवाद, दोस्तों, आपको नहीं पता कि आपकी पोस्ट कितनी मूल्यवान थी! अंत में, चीजें कुछ समझने शुरू कर रही हैं। –