Permalink
Browse files

- Publish the parser grammar

- rename the grammar module from 'grammar_sip' to 'grammar'
- rename the grammar file from 'grammar_rfc3261.js' to 'grammar.js'
- Adapt the code in JsSIP to the module name
  • Loading branch information...
1 parent 6d3afac commit a935ad2af15576b8fb7cae2a62db0ce9c23b1ef2 @jmillan jmillan committed Oct 25, 2012
View
@@ -42,14 +42,14 @@ module.exports = function(grunt) {
post: {
src: [
'dist/<%= pkg.name %>-<%= pkg.version %>.js',
- "src/grammar/grammar_rfc3261.js"
+ "src/grammar/dist/grammar.js"
],
dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.js'
},
post_min: {
src: [
'dist/<%= pkg.name %>-<%= pkg.version %>.min.js',
- "src/grammar/grammar_rfc3261.min.js"
+ "src/grammar/dist/grammar.min.js"
],
dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.min.js'
}
View
@@ -171,7 +171,7 @@ JsSIP.Parser = (function() {
// Parse first line. Check if it is a Request or a Reply.
firstLine = data.substring(0, header_end);
- parsed = JsSIP.grammar_sip.parse(firstLine, 'Request_Response');
+ parsed = JsSIP.grammar.parse(firstLine, 'Request_Response');
if(parsed === -1) {
console.log(JsSIP.c.LOG_PARSER +'Error parsing first line of SIP message: "' + firstLine + '"');
View
@@ -282,7 +282,7 @@ JsSIP.IncomingMessage.prototype = {
//substitute '-' by '_' for grammar rule matching.
name = name.replace(/-/g, '_');
- parsed = JsSIP.grammar_sip.parse(value, name);
+ parsed = JsSIP.grammar.parse(value, name);
if(parsed === -1) {
this.headers[name].splice(idx, 1); //delete from headers
View
@@ -635,7 +635,7 @@ JsSIP.UA.prototype.loadConfig = function(configuration) {
//for this instance.
settings.jssip_id = Math.random().toString(36).substr(2, 5);
- uri = JsSIP.grammar_sip.parse(settings.uri, 'lazy_uri');
+ uri = JsSIP.grammar.parse(settings.uri, 'lazy_uri');
settings.user = uri.user;
settings.domain = uri.host;
@@ -662,7 +662,7 @@ JsSIP.UA.prototype.loadConfig = function(configuration) {
// Transports
for (idx in configuration.outbound_proxy_set) {
- ws_uri = JsSIP.grammar_sip.parse(settings.outbound_proxy_set[idx].ws_uri, 'absoluteURI');
+ ws_uri = JsSIP.grammar.parse(settings.outbound_proxy_set[idx].ws_uri, 'absoluteURI');
settings.outbound_proxy_set[idx].sip_uri = '<sip:' + ws_uri.host + (ws_uri.port ? ':' + ws_uri.port : '') + ';transport=ws;lr>';
@@ -776,7 +776,7 @@ JsSIP.UA.configuration_check = {
return false;
}
- url = JsSIP.grammar_sip.parse(outbound_proxy_set[idx].ws_uri, 'absoluteURI');
+ url = JsSIP.grammar.parse(outbound_proxy_set[idx].ws_uri, 'absoluteURI');
if(url === -1) {
console.log(JsSIP.c.LOG_UA +'Invalid "ws_uri" attribute in outbound_proxy_set parameter: ' + outbound_proxy_set[idx].ws_uri);
@@ -791,7 +791,7 @@ JsSIP.UA.configuration_check = {
uri: function(uri) {
var parsed;
- parsed = JsSIP.grammar_sip.parse(uri, 'lazy_uri');
+ parsed = JsSIP.grammar.parse(uri, 'lazy_uri');
if(parsed === -1) {
console.log(JsSIP.c.LOG_UA +'Invalid uri: ' + uri);
@@ -804,7 +804,7 @@ JsSIP.UA.configuration_check = {
}
},
password: function(password) {
- if(JsSIP.grammar_sip.parse(password, 'password') === -1) {
+ if(JsSIP.grammar.parse(password, 'password') === -1) {
return false;
} else {
return true;
@@ -813,7 +813,7 @@ JsSIP.UA.configuration_check = {
},
optional: {
authorization_user: function(authorization_user) {
- if(JsSIP.grammar_sip.parse('"'+ authorization_user +'"', 'quoted_string') === -1) {
+ if(JsSIP.grammar.parse('"'+ authorization_user +'"', 'quoted_string') === -1) {
return false;
} else {
return true;
@@ -828,7 +828,7 @@ JsSIP.UA.configuration_check = {
}
},
display_name: function(display_name) {
- if(JsSIP.grammar_sip.parse(display_name, 'display_name') === -1) {
+ if(JsSIP.grammar.parse(display_name, 'display_name') === -1) {
return false;
} else {
return true;
@@ -844,7 +844,7 @@ JsSIP.UA.configuration_check = {
stun_server: function(stun_server) {
var parsed;
- parsed = JsSIP.grammar_sip.parse(stun_server, 'hostport');
+ parsed = JsSIP.grammar.parse(stun_server, 'hostport');
if(parsed === -1) {
console.log(JsSIP.c.LOG_UA +'Invalid stun_server: ' + stun_server);
View
@@ -0,0 +1,72 @@
+JsSIP Parser Grammar
+======================
+
+JsSIP uses [PEG.js](https://github.com/dmajda/pegjs) to build its parser grammar, a PEG based parser generator for JavaScript.
+
+The grammar source is defined in PEG format in `src/grammar.pegjs` file. It must be converted to JavaScript by using PEG.js
+
+
+PEG.js Installation
+------------------
+
+In order to use the `pegjs` node command, install PEG.js globally:
+
+ $ npm install -g pegjs
+
+
+Generating the grammar parser from the grammar source
+-----------------------------------------------------
+
+The following command converts the PEG grammar into a JsSIP module named `grammar`. The output file is created in `dist/grammar.js`.
+
+ $ pegjs -e JsSIP.grammar src/grammar.pegjs dist/grammar.js
+
+In case there is an error in the grammar, the command will throw a descriptive error.
+
+Once compiled, there are couple of changes that need to be done in `dist/grammar.js`. This is because the PEG.js grammar parser, by default, returns an Array (representing a splitted version of the input) if the input matched the given rule, but JsSIP `grammar.pegjs` generates internally a SIP Header Oject instead and this is what JsSIP expects as the result of the `grammar.parse()` function.
+
+The changes to be done in `dist/grammar.js` file are located at the end of the `parse()` function, just where it returns the Array for successful parsing or throws an exception for parsing error:
+
+* Return `-1` instead of throwing an exception for a parsing error.
+* Return expected `msg` object instead of the default Array for a successful parsing.
+
+```
+ if (result === null || pos !== input.length) {
+ var offset = Math.max(pos, rightmostFailuresPos);
+ var found = offset < input.length ? input.charAt(offset) : null;
+ var errorPosition = computeErrorPosition();
+
+- throw new this.SyntaxError(`
++ new this.SyntaxError(
+ cleanupExpected(rightmostFailuresExpected),
+ found,
+ offset,
+ errorPosition.line,
+ errorPosition.column
+ );
+
++ return -1;
+ }
+
+- return result;
++ return msg;
+ },
+
+ /* Returns the parser source code. */
+ toSource: function() { return this._source; }
+```
+
+Minifying the grammar parser
+-----------------------------
+
+[node-minify](https://github.com/srod/node-minify) is used in order to minify the generated grammar.
+
+Install node-minify
+
+ $ npm install node-minify
+
+Run the `minify.js` script with node command to minimize the grammar.
+
+ $ node minify.js
+
+This will generate the `dist/grammar.min.js` file.
Oops, something went wrong.

1 comment on commit a935ad2

Contributor

saghul commented on a935ad2 Oct 25, 2012

🍰

Please sign in to comment.