2012-02-08 22 views
9

Próbuję parsować JavaScript (ECMASCript) za pomocą C#.C#, ANTLR, gramatyka ECMAScript

znalazłem następujące instrukcje na temat tworzenia nowego projektu: http://www.antlr.org/wiki/pages/viewpage.action?pageId=557075

Tak już pobrane ANTLRWorks, ANTLR v3, rozpakowałem ANTLR, stworzyli projekt VS2010 (.NET4), dodaje odniesień, sprawdzane i generowane Gramatyka.

Potem otrzymaliśmy wiele błędów kompilacji:

The type or namespace name 'AstParserRuleReturnScope' could not be found (are you missing a using directive or an assembly reference?)

The type or namespace name 'GrammarRule' could not be found (are you missing a using directive or an assembly reference?)

Stackoverlowed dla nich i ma rozwiązanie: antlr c# errors when integrating into VS2008

Więc Pobrałem nowy czas pracy, zastąp starą i rekompilacji projektu i dostał

The name 'HIDDEN' does not exist in the current context d:\Workspace.1\ScriptParser\ScriptParser\TestLexer.cs

ok, zmieniłem ukryte Ukryte jako zalecane w poniższej rozmowie w: [antlr-interest] How viable is the Csharp3 target? (more specific questions)

Teraz próbuję przeanalizować dane wejściowe. Znalazłem kilka przykładów i napisał następujący kod:

using Antlr.Runtime; 
namespace ScriptParser 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var stream = new ANTLRStringStream("1+2"); 
      var lexer = new TestLexer(stream); 
      var tokenStream = new CommonTokenStream(lexer); 
      var parser = new TestParser(tokenStream); 
      // what exactly should be here??? 
     } 
    } 
} 

moim celem jest parser JavaScript plik z antlr ale wydaje się, że będzie to nie jest tak proste, jak myślałem ...

Aktualizacja :

Jak sugerowano w Why are antlr3 c# parser methods private? mam zmodyfikowany gramatykę Test.g poprzez dodanie „publiczne” zmodyfikowany przed panowaniem expr:

public expr : mexpr (PLUS^ mexpr)* SEMI! 
; 

a następnie regenerowany kodu zastąpiono Ukryty ukryty (ponownie), a zmodyfikowali kodu w następujący sposób:

var stream = new ANTLRStringStream("1+2"); 
var lexer = new TestLexer(stream); 
var tokenStream = new CommonTokenStream(lexer); 
var parser = new TestParser(tokenStream); 
var result = parser.expr(); 
var tree = (CommonTree)result.Tree; 

i nie jest on awarii na linii

root_0 = (object)adaptor.Nil(); 

w następnym kodem generowanych

try { DebugEnterRule(GrammarFileName, "expr"); 
DebugLocation(7, 0); 
try 
{ 
    // d:\\Workspace.1\\ScriptParser\\ScriptParser\\Test.g:7:13: (mexpr (PLUS^mexpr)* SEMI !) 
    DebugEnterAlt(1); 
    // d:\\Workspace.1\\ScriptParser\\ScriptParser\\Test.g:7:15: mexpr (PLUS^mexpr)* SEMI ! 
    { 
    root_0 = (object)adaptor.Nil(); 

    DebugLocation(7, 15); 
    PushFollow(Follow._mexpr_in_expr31); 

z komunikatem NullReferenceException, ponieważ adapter ma wartość NULL.

mam rozwiązany przez dodanie

parser.TreeAdaptor = new CommonTreeAdaptor(); 

UPDATE 2:

Tak, wreszcie zacząłem z moim podstawowym zadaniem: analizowania JavaScript.

ANTLR highlights gramatyka ECMAScript autorstwa Chrisa Lambrou.

Więc ja generowane lexer/parser i uruchomić go z bardzo prostego kodu JavaScript:

var f = function() { }; 

i parsowanie nie powiedzie się z następującym wyjściu z tree.ToStringTree():

<error: var q = function() { };> 
+0

Zamówienie tego poprzedniego pytania i odpowiedzi: http://stackoverflow.com/questions/4396080/antlr-3-3-carp-tutorials –

+0

Dziękuję za doskonały tutorial. Jak rozumiem, zasady gramatyki powinny zostać zamienione na metody. Używam gramatyki z http://www.antlr.org/wiki/pages/viewpage.action?pageId=557075 i ANTLRWorks generuję "expr", "atom" i inne metody, ale są one prywatne. –

+0

Dzięki Alex. W.r.t. prywatne metody (reguły parsera), zobacz inne pytania i odpowiedzi: http://stackoverflow.com/questions/6411520/why-are-antlr3-c-sharp-parser-methods-private –

Odpowiedz

1

Twoja reguła gramatyczna mówi, że na końcu wyrażenia powinien znajdować się średnik, ale w tobie główna funkcja:

var stream = new ANTLRStringStream("1+2"); 

brakuje średnika. Czy nie powinno to być "1 + 2;"?

+0

Z pewnością "1 + 2;" jest prawidłowym Javascriptem. Ale tak samo jest "1 + 2" (lub przynajmniej "1 + 2 \ n"). W jaki sposób gramatyka ANTLR obsługuje brakujące ";" pytanie? –