syntax icon indicating copy to clipboard operation
syntax copied to clipboard

Need recommendation for namespace management

Open fdutton opened this issue 8 years ago • 3 comments

I have the following BNF rules and I have the functions disjunction and conjunction declared in the moduleInclude section.

["E OR E",  "$$ = disjunction($1, $3)"],
["E AND E",  "$$ = conjunction($1, $3)"],

This places the functions in the global namespace. Is there a way to add these functions to the generated parser or can you recommend an idiom that does not pollute the global namespace? In other words, given two parsers that both declare the functions disjunction and conjunction how would I isolate the two parsers?

fdutton avatar Feb 14 '17 21:02 fdutton

The moduleInclude code is injected at the beginning (or at the end -- depending on a plugin) of the generated parser.

For some languages, like JS or Python, those function become as part of the generated module, and are not exposed to the outside (so naming collision doesn't exist there). For other languages like PHP, which just include the whole source code into the importing namespace, the solution might be defining not just global functions, but functions (probably static) within a class or a namespace. In addition, the DisjunctionNode can be a class itself.

%{
namespace MyBool;

class Disjunction {
  public function __construct($left, $right) {
    ...
  }
}

%}

%%

E
  : E OR E  { $$ = new \MyBool\Disjunction($1, $3); }
  | E AND E { $$ = new \MyBool\Conjunction($1, $3) }
  ;

DmitrySoshnikov avatar Feb 14 '17 22:02 DmitrySoshnikov

Actually, for 2 same parser instances, see issue #17. We need to make not static parse function, but to create a parser instance, and then call $parser->parse().

For moduleInclude though, you can define AST node classes as separate files, and then just require_once in the moduleInclude:

%{

require_once "DisjunctionNode.php"
...

}%

DmitrySoshnikov avatar Feb 14 '17 22:02 DmitrySoshnikov

Note: https://github.com/DmitrySoshnikov/syntax/commit/7ffd6fcf527cb2a3eac4fa41c2cd6abb010412f7 added support for namespace option using --namespace 'MyNamespace'. For PHP, a thrown exception will be MyNamespace\SyntaxException instead of just SyntaxException. Also a parser should be used via namespace in this case: MyNamespace\MyParser::parse(...). If no namespace is provided, it's as previously as MyParser::parser(...).

DmitrySoshnikov avatar Feb 15 '17 23:02 DmitrySoshnikov