2012-02-20 15 views
6

पाठ को पार्स करते समय, मुझे नीचे दिए गए कोड के बाद सामान्य रूप में मिनी-स्टेट-मशीनों को लागू करने की आवश्यकता होती है।क्या टेक्स्ट पार्स करते समय राज्य मशीनों को लागू करने के लिए कोई अच्छा सीपीएएन मॉड्यूल है?

क्या कोई सीपीएएन मॉड्यूल है जिसे "सर्वोत्तम अभ्यास" माना जाता है और यह एक आसान और सुरुचिपूर्ण तरीके से राज्य मशीन तर्क को लागू करने के लिए उपयुक्त है?

मैं समाधान Parse::RecDescent की तुलना में कम जटिल है, लेकिन अगर कोई भी मौजूद हैं और Parse::RecDescent इस समस्या का लागू करने के लिए की तुलना में मैंने सोचा था कि बहुत आसान है, मैं बहुत बजाय इसे पर विचार मेरे अपने रोलिंग की तरह मैं बहुत किया गया है करने को तैयार हूँ पसंद करेंगे दूर।

उदाहरण सामान्य पार्स कोड:

my $state = 1; 
while (my $token = get_next_token()) { # Usually next line 
    if ($state == 1) { 
     do_state1_processing(); 
     if (token_matches_transition_1_to_2($token)) { 
      do_state_1_to_2_transition_processing(); 
      $state == 2; 
      next; 
     } elsif (token_matches_transition_1_to_4($token)) { 
      do_state_1_to_4_transition_processing(); 
      $state == 4; 
      next; 
     } else { 
      do_state1_continuation(); 
      next; 
     } 
    } elsif ($state == 5) { 
     do_state5_processing(); 
     if (token_matches_transition_5_to_6($token)) { 
      do_state_5_to_6_transition_processing(); 
      $state == 6; 
      next; 
     } elsif (token_matches_transition_5_to_4($token)) { 
      do_state_5_to_4_transition_processing(); 
      $state == 4; 
      next; 
     } else { 
      do_state5_continuation(); 
      next; 
     } 
    } else { 

    } 

} 
+3

'एफएसए :: नियम 'के बारे में क्या? (यहां दिए गए 'डीएफए :: *' मॉड्यूल [यहां] (http://www.perl.com/pub/2004/09/23/fsms.html) एक और लीड हो सकता है)। – Ouki

+3

मैं स्वयं इस तरह के मामले में अगले राज्य को लौटने वाले सब के एक हैश का उपयोग करूंगा। हालांकि, मैं देखना चाहता हूं कि और भी क्या उपयोग किया जा सकता है। – Dallaylaen

+0

@ दलायलेन: मेरा विचार बिल्कुल, लेकिन डीवीके ने मॉड्यूल के लिए कहा;) – Ouki

उत्तर

3

मैं Marpa और Marpa::XS पर एक नज़र डालने की सिफारिश करेंगे।

बस this simple calculator देखें।

my $grammar = Marpa::XS::Grammar->new(
    { start => 'Expression', 
     actions => 'My_Actions', 
     default_action => 'first_arg', 
     rules => [ 
      { lhs => 'Expression', rhs => [qw'Term'] }, 
      { lhs => 'Term', rhs => [qw'Factor'] }, 
      { lhs => 'Factor', rhs => [qw'Number'] }, 
      { lhs => 'Term', rhs => [qw'Term Add Term'], action => 'do_add' }, 
      { lhs => 'Factor', 
       rhs => [qw'Factor Multiply Factor'], 
       action => 'do_multiply' 
      }, 
     ], 
    } 
); 

आपको टोकननाइज़र को स्वयं लागू करना होगा।

+1

मार्पा का उपयोग करके गणितीय इकाइयों को पार्स करना: https://github.com/jberger/Math-ParseUnit –

2

आप Class::StateMachine उपयोग कर सकते हैं:

package Foo; 
use parent 'Class::StateMachine'; 

sub new { 
    my $class = shift; 
    Class::StateMachine::bless {}, $class, 'state_1'; 
} 

sub do_state_processing :OnState('state_1') { 
    my $self = shift; 
    if (...) { $self->event_1 } 
    elsif (...) { $self->event_2 } 
    ... 
} 

sub do_state_processing :OnState('state_2') { 
    ... 
} 

sub event_1 :OnState('state_1') { 
    my $self = shift; 
    $self->state('state_2'); 
} 

sub event_2 :OnState('state_2') { 
    my $self = shift; 
    $self->state('state_3'); 
} 

sub enter_state :OnState('state_1') { 
    print "entering state 1"; 
    ... 
} 

sub enter_state :OnState('state_2') { 
    ... 
} 

package main; 

my $sm = Foo->new; 
... 
while (my $token = get_next_token()) { 
    $sm->do_state_processing; 
} 

हालांकि, एक मॉड्यूल पाठ प्रसंस्करण के लिए विशिष्ट शायद अपने विशेष मामले के लिए अधिक उपयुक्त होगा

1

(मदद के साथ) मैं कुछ कुछ साल पहले लिखा था बुलाया Perl Formal Language Toolkit तो यह किसी प्रकार के आधार के रूप में काम कर सकता है, हालांकि मुझे लगता है कि आपको वास्तव में चाहते हैं Ragel Finite State Machine Compiler जैसे टूल। दुर्भाग्यवश, यह पर्ल पर आउटपुट नहीं करता है, और यह Ragel के लिए पर्ल लक्ष्य को लागू करने के लिए मेरी बैक-बर्नर इच्छा है और मेरे बिट-रोटिंग मॉड्यूल के लिए समान (लेकिन अधिक पर्ल उन्मुख) सुविधाएं भी प्रदान करता है।

0

मैं Parser::MGC लिखा ज्यादातर क्योंकि मैं Parse::RecDescent उचित त्रुटि रिपोर्टिंग काफी मुश्किल था करने के लिए प्राप्त करने की कोशिश पाया, और मैं स्ट्रिंग, कोट कि पर्ल कोड होता है, अन्य पर्ल कोड के साथ में अपनी विचित्र कस्टम एम्बेडेड व्याकरण पसंद नहीं आया। एक P::MGC कार्यक्रम सिर्फ perl कोड है; लेकिन P::RD के समान व्याकरण संरचना पर एक पुनरावर्ती वंश के रूप में लिखा गया है।