2012-04-03 6 views
1

Ich analysiere eine Verilog-Datei, um die Abhängigkeiten darin zu extrahieren. Ich muss die meisten Modulinhalte nicht analysieren, bin aber nur an Include-Anweisungen und Modulinstanziationen interessiert. Ich versuche zuerst, nur die Include-Anweisungen zu extrahieren. Dies ist mein Code so weit:Wie analysiere ich ausgewählte Ausdrücke bis zu einem Ende-Schlüsselwort in pyparsing

include_pragma = Group(Keyword("`include") + quotedString + lineEnd.suppress()) 
module_definition = ZeroOrMore(~Keyword("endmodule") + MatchFirst([include_pragma, restOfLine])) + Keyword("endmodule") 

Mein Punkt ist, dass ich entweder wird ein Pragma umfassen übereinstimmen, oder eine Reihe von nichts, bis ich „endmodule“ erreichen. Wenn ich diese Grammatik auf der folgenden Saite ausprobiere, gerät Pyparssing in eine Art Endlosschleife.

`include "InternalInclude.v" 

localparam COMMA_WIDTH = 10; 

localparam UNKNOWN = 1'b0, 
      KNOWN = 1'b1; 

reg  [DATA_WIDTH-1:0] TtiuPosQ2; 
reg      TtiuDetQ2; 
reg  [   7:0] TtiuDetQ2Save; 

assign DebugQO = { DataQI,   // 65:34 
        TxTrainingEnQI, // 33 
        TtiuDetQ2,  // 32 
        TtiuPosQ2  // 31:0 
        }; 

always @(posedge Clk or posedge ResetI) begin 
    if (ResetI) begin 
     CommaPosQO <= {(DATA_WIDTH){1'b0}}; 
     CommaDetQO <= 0; 
     CommaPosQ1 <= {(DATA_WIDTH){1'b0}}; 
     CommaPosQ2 <= {(DATA_WIDTH){1'b0}}; 
     CommaDetQ2 <= 0; 
     StateQ <= 0; 

     CommaPosSaveQ <= {(DATA_WIDTH){1'b0}}; 
     TtiuPosQ1 <= 0; 
     TtiuPosQ2 <= 0; 
     TtiuDetQ2 <= 0; 
     TtiuDetQ2Save <= 8'h00; 
    end 
    else begin 
     CommaPosQO <= CommaPosC2; 
     CommaDetQO <= CommaDetC2; 
     CommaPosQ1 <= CommaPosC; 
     CommaPosQ2 <= CommaPosQ1; 
     CommaDetQ2 <= (| CommaPosQ1); 
     StateQ <= StateC; 
     CommaPosSaveQ <= CommaPosSaveC; 
     TtiuPosQ1 <= TtiuPosC1; 
     TtiuPosQ2 <= TtiuPosC2; 
     TtiuDetQ2 <= TtiuDetC2; 
     TtiuDetQ2Save <= TtiuDetQ2 ? 8'hFF : {1'b0, TtiuDetQ2Save[7:1]}; 
    end 
end 

endmodule 

Ich bin wahrscheinlich Missverständnis der ~ Operator. Irgendwelche Vorschläge?

Update

Nach dem setDebug() -Methode vorgeschlagen, fand ich, dass die Endlosschleifen diese druckt:

Match {Group:({"`include" quotedString using single or double quotes Suppress:(lineEnd)}) | Re:('.*')} at loc 0(1,1) 
Matched {Group:({"`include" quotedString using single or double quotes Suppress:(lineEnd)}) | Re:('.*')} -> [['`include' 
, '"InternalInclude.v"']] 
Match {Group:({"`include" quotedString using single or double quotes Suppress:(lineEnd)}) | Re:('.*')} at loc 31(4,1) 
Matched {Group:({"`include" quotedString using single or double quotes Suppress:(lineEnd)}) | Re:('.*')} -> [''] 
Match {Group:({"`include" quotedString using single or double quotes Suppress:(lineEnd)}) | Re:('.*')} at loc 31(4,1) 
Matched {Group:({"`include" quotedString using single or double quotes Suppress:(lineEnd)}) | Re:('.*')} -> [''] 
Match {Group:({"`include" quotedString using single or double quotes Suppress:(lineEnd)}) | Re:('.*')} at loc 31(4,1) 
Matched {Group:({"`include" quotedString using single or double quotes Suppress:(lineEnd)}) | Re:('.*')} -> [''] 

ist etwas, das ich die Parse-Position tun was nicht vorwärts zu bewegen?

+2

ändern 'Or' zu' MatchFirst', Sie tun, zusätzliche Arbeit mit 'Or', wenn Sie eine Richtlinie enthalten übereinstimmen, und in der Tat wahrscheinlich Tests zu tun, dass Sie * nicht * möchte tun. Sie können die Parsing-Aktivität eines bestimmten Ausdrucks mit 'setDebug()' überwachen. 'setDebug' meldet jeden Versuch der Analyse und meldet dann, ob die Analyse erfolgreich war oder fehlgeschlagen ist. Versuchen Sie 'restOfLine' in Ihrer Grammatik in' restofLine.setDebug() 'zu ändern und sehen Sie, ob diese Ausgabe hilfreich ist. – PaulMcG

+0

@PaulMcGuire Ich habe versucht, was Sie gesagt haben und bekam die Ausgabe wie in meiner Bearbeitung gezeigt. –

+0

@PaulMcGuire siehe meine Antwort –

Antwort

1

Das Problem lag in der Verwendung des RestOfLine-Ausdrucks. Es kann alles passen, einschließlich "". So würde gehen der Parser wie folgt:

  1. include "InternalInclude.v" Matched
  2. Match ''
  3. Spiel, das gleiche restOfLine '' zu restOfLine, weil es nicht die \ n verbrauchen haben, und es gibt nach wie vor '' links vor dem \ n, wie es alwasy sein;)

es zu beheben, änderte ich restOfLine zu (restOfLine + lineEnd). Dies zwang den Parser dazu, \ n nach dem Anpassen der Zeile zu verbrauchen. Der neue Parser liest:

include_pragma = Group(Keyword("`include") + quotedString + lineEnd.suppress()) 
module_definition = ZeroOrMore(~Keyword("endmodule") + MatchFirst([include_pragma, (restOfLine + lineEnd)])) + Keyword("endmodule") 
+1

Sie könnten auch in die Verwendung von ScanString oder searchString anstelle von ParseString suchen. scan/searchString sind nützlich, wenn Sie nur Teile einer Datei auswählen und das Ganze nicht analysieren wollen. Ich glaube, du kommst vielleicht sogar mit '(include_pragma | Keyword (" endmodule ")) durch. ScanString (verilog_text)'. – PaulMcG

Verwandte Themen